mcp-rubber-duck 1.2.5 → 1.3.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.
Files changed (41) hide show
  1. package/.eslintrc.json +1 -0
  2. package/CHANGELOG.md +12 -0
  3. package/README.md +116 -2
  4. package/dist/config/types.d.ts +78 -0
  5. package/dist/config/types.d.ts.map +1 -1
  6. package/dist/server.d.ts.map +1 -1
  7. package/dist/server.js +150 -0
  8. package/dist/server.js.map +1 -1
  9. package/dist/services/consensus.d.ts +28 -0
  10. package/dist/services/consensus.d.ts.map +1 -0
  11. package/dist/services/consensus.js +257 -0
  12. package/dist/services/consensus.js.map +1 -0
  13. package/dist/tools/duck-debate.d.ts +16 -0
  14. package/dist/tools/duck-debate.d.ts.map +1 -0
  15. package/dist/tools/duck-debate.js +272 -0
  16. package/dist/tools/duck-debate.js.map +1 -0
  17. package/dist/tools/duck-iterate.d.ts +14 -0
  18. package/dist/tools/duck-iterate.d.ts.map +1 -0
  19. package/dist/tools/duck-iterate.js +195 -0
  20. package/dist/tools/duck-iterate.js.map +1 -0
  21. package/dist/tools/duck-judge.d.ts +15 -0
  22. package/dist/tools/duck-judge.d.ts.map +1 -0
  23. package/dist/tools/duck-judge.js +208 -0
  24. package/dist/tools/duck-judge.js.map +1 -0
  25. package/dist/tools/duck-vote.d.ts +14 -0
  26. package/dist/tools/duck-vote.d.ts.map +1 -0
  27. package/dist/tools/duck-vote.js +46 -0
  28. package/dist/tools/duck-vote.js.map +1 -0
  29. package/package.json +1 -1
  30. package/src/config/types.ts +92 -0
  31. package/src/server.ts +154 -0
  32. package/src/services/consensus.ts +324 -0
  33. package/src/tools/duck-debate.ts +383 -0
  34. package/src/tools/duck-iterate.ts +253 -0
  35. package/src/tools/duck-judge.ts +301 -0
  36. package/src/tools/duck-vote.ts +87 -0
  37. package/tests/consensus.test.ts +282 -0
  38. package/tests/duck-debate.test.ts +286 -0
  39. package/tests/duck-iterate.test.ts +249 -0
  40. package/tests/duck-judge.test.ts +296 -0
  41. package/tests/duck-vote.test.ts +250 -0
@@ -0,0 +1,257 @@
1
+ import { logger } from '../utils/logger.js';
2
+ export class ConsensusService {
3
+ /**
4
+ * Build a voting prompt that asks the LLM to vote on options
5
+ */
6
+ buildVotePrompt(question, options, requireReasoning = true) {
7
+ const optionsList = options.map((opt, i) => `${i + 1}. ${opt}`).join('\n');
8
+ const format = requireReasoning
9
+ ? `{
10
+ "choice": "<exact option text>",
11
+ "confidence": <0-100>,
12
+ "reasoning": "<brief explanation>"
13
+ }`
14
+ : `{
15
+ "choice": "<exact option text>",
16
+ "confidence": <0-100>
17
+ }`;
18
+ return `You are voting on the following question. You MUST choose exactly ONE option from the list below.
19
+
20
+ QUESTION: ${question}
21
+
22
+ OPTIONS:
23
+ ${optionsList}
24
+
25
+ INSTRUCTIONS:
26
+ 1. Analyze each option carefully
27
+ 2. Choose the BEST option based on your knowledge and reasoning
28
+ 3. Respond with ONLY a JSON object in this exact format:
29
+
30
+ ${format}
31
+
32
+ IMPORTANT:
33
+ - "choice" must be the EXACT text of one of the options above
34
+ - "confidence" must be a number from 0 to 100
35
+ - Do NOT include any text before or after the JSON
36
+ - Do NOT use markdown code blocks`;
37
+ }
38
+ /**
39
+ * Parse a vote from an LLM response
40
+ */
41
+ parseVote(response, voter, nickname, options) {
42
+ const result = {
43
+ voter,
44
+ nickname,
45
+ choice: '',
46
+ confidence: 0,
47
+ reasoning: '',
48
+ rawResponse: response,
49
+ };
50
+ try {
51
+ // Try to extract JSON from the response (greedy to handle nested objects)
52
+ const jsonMatch = response.match(/\{[\s\S]*\}/);
53
+ if (!jsonMatch) {
54
+ logger.warn(`No JSON found in vote response from ${voter}`);
55
+ return this.fallbackParse(response, voter, nickname, options);
56
+ }
57
+ const parsed = JSON.parse(jsonMatch[0]);
58
+ // Validate choice
59
+ const choice = parsed.choice?.toString().trim();
60
+ if (choice) {
61
+ // Try exact match first
62
+ const exactMatch = options.find(opt => opt.toLowerCase() === choice.toLowerCase());
63
+ if (exactMatch) {
64
+ result.choice = exactMatch;
65
+ }
66
+ else {
67
+ // Try partial match
68
+ const partialMatch = options.find(opt => opt.toLowerCase().includes(choice.toLowerCase()) ||
69
+ choice.toLowerCase().includes(opt.toLowerCase()));
70
+ if (partialMatch) {
71
+ result.choice = partialMatch;
72
+ logger.debug(`Fuzzy matched "${choice}" to "${partialMatch}" for ${voter}`);
73
+ }
74
+ }
75
+ }
76
+ // Parse confidence
77
+ if (typeof parsed.confidence === 'number') {
78
+ result.confidence = Math.max(0, Math.min(100, parsed.confidence));
79
+ }
80
+ else if (typeof parsed.confidence === 'string') {
81
+ const conf = parseFloat(parsed.confidence);
82
+ if (!isNaN(conf)) {
83
+ result.confidence = Math.max(0, Math.min(100, conf));
84
+ }
85
+ }
86
+ // Parse reasoning
87
+ if (parsed.reasoning) {
88
+ result.reasoning = parsed.reasoning.toString().trim();
89
+ }
90
+ }
91
+ catch (error) {
92
+ logger.warn(`Failed to parse JSON vote from ${voter}:`, error);
93
+ return this.fallbackParse(response, voter, nickname, options);
94
+ }
95
+ return result;
96
+ }
97
+ /**
98
+ * Fallback parsing when JSON fails - try to extract choice from text
99
+ */
100
+ fallbackParse(response, voter, nickname, options) {
101
+ const result = {
102
+ voter,
103
+ nickname,
104
+ choice: '',
105
+ confidence: 50, // Default confidence for fallback
106
+ reasoning: 'Vote extracted via fallback parsing',
107
+ rawResponse: response,
108
+ };
109
+ // Try to find any option mentioned in the response
110
+ const responseLower = response.toLowerCase();
111
+ for (const option of options) {
112
+ if (responseLower.includes(option.toLowerCase())) {
113
+ result.choice = option;
114
+ logger.debug(`Fallback parsed choice "${option}" from ${voter}`);
115
+ break;
116
+ }
117
+ }
118
+ return result;
119
+ }
120
+ /**
121
+ * Aggregate votes into a final result
122
+ */
123
+ aggregateVotes(question, options, votes) {
124
+ // Initialize tally and confidence tracking
125
+ const tally = {};
126
+ const confidenceSums = {};
127
+ const confidenceCounts = {};
128
+ for (const option of options) {
129
+ tally[option] = 0;
130
+ confidenceSums[option] = 0;
131
+ confidenceCounts[option] = 0;
132
+ }
133
+ // Count votes
134
+ let validVotes = 0;
135
+ for (const vote of votes) {
136
+ if (vote.choice && options.includes(vote.choice)) {
137
+ tally[vote.choice]++;
138
+ confidenceSums[vote.choice] += vote.confidence;
139
+ confidenceCounts[vote.choice]++;
140
+ validVotes++;
141
+ }
142
+ }
143
+ // Calculate average confidence per option
144
+ const confidenceByOption = {};
145
+ for (const option of options) {
146
+ confidenceByOption[option] = confidenceCounts[option] > 0
147
+ ? Math.round(confidenceSums[option] / confidenceCounts[option])
148
+ : 0;
149
+ }
150
+ // Determine winner
151
+ const maxVotes = Math.max(...Object.values(tally));
152
+ const winners = options.filter(opt => tally[opt] === maxVotes && maxVotes > 0);
153
+ const isTie = winners.length > 1;
154
+ let winner = null;
155
+ if (winners.length === 1) {
156
+ winner = winners[0];
157
+ }
158
+ else if (isTie && winners.length > 0) {
159
+ // Break tie by confidence
160
+ let highestConfidence = -1;
161
+ for (const w of winners) {
162
+ if (confidenceByOption[w] > highestConfidence) {
163
+ highestConfidence = confidenceByOption[w];
164
+ winner = w;
165
+ }
166
+ }
167
+ }
168
+ // Determine consensus level
169
+ const consensusLevel = this.determineConsensusLevel(validVotes, votes.length, maxVotes, isTie);
170
+ return {
171
+ question,
172
+ options,
173
+ winner,
174
+ isTie,
175
+ tally,
176
+ confidenceByOption,
177
+ votes,
178
+ totalVoters: votes.length,
179
+ validVotes,
180
+ consensusLevel,
181
+ };
182
+ }
183
+ /**
184
+ * Determine the level of consensus reached
185
+ */
186
+ determineConsensusLevel(validVotes, totalVoters, maxVotes, isTie) {
187
+ if (validVotes === 0) {
188
+ return 'none';
189
+ }
190
+ const winnerRatio = maxVotes / validVotes;
191
+ if (winnerRatio === 1 && validVotes === totalVoters) {
192
+ return 'unanimous';
193
+ }
194
+ else if (winnerRatio > 0.5) {
195
+ return 'majority';
196
+ }
197
+ else if (!isTie && maxVotes > 0) {
198
+ return 'plurality';
199
+ }
200
+ else if (isTie) {
201
+ return 'split';
202
+ }
203
+ return 'none';
204
+ }
205
+ /**
206
+ * Format the aggregated vote result for display
207
+ */
208
+ formatVoteResult(result) {
209
+ let output = `šŸ—³ļø **Vote Results**\n`;
210
+ output += `═══════════════════════════════════════\n\n`;
211
+ output += `**Question:** ${result.question}\n\n`;
212
+ // Winner announcement
213
+ if (result.winner) {
214
+ const emoji = result.consensusLevel === 'unanimous' ? 'šŸ†' :
215
+ result.consensusLevel === 'majority' ? 'āœ…' : 'šŸ“Š';
216
+ output += `${emoji} **Winner:** ${result.winner}`;
217
+ if (result.isTie) {
218
+ output += ` (tie-breaker by confidence)`;
219
+ }
220
+ output += `\n`;
221
+ output += `šŸ“ˆ **Consensus:** ${result.consensusLevel}\n\n`;
222
+ }
223
+ else {
224
+ output += `āš ļø **No valid votes recorded**\n\n`;
225
+ }
226
+ // Vote tally
227
+ output += `**Vote Tally:**\n`;
228
+ const sortedOptions = [...result.options].sort((a, b) => result.tally[b] - result.tally[a]);
229
+ for (const option of sortedOptions) {
230
+ const votes = result.tally[option];
231
+ const confidence = result.confidenceByOption[option];
232
+ const bar = 'ā–ˆ'.repeat(Math.min(votes * 3, 15));
233
+ const isWinner = option === result.winner;
234
+ const marker = isWinner ? ' šŸ‘‘' : '';
235
+ output += ` ${option}: ${bar} ${votes} vote(s) (avg confidence: ${confidence}%)${marker}\n`;
236
+ }
237
+ output += `\n**Individual Votes:**\n`;
238
+ output += `─────────────────────────────────────\n`;
239
+ for (const vote of result.votes) {
240
+ if (vote.choice) {
241
+ output += `šŸ¦† **${vote.nickname}** voted: **${vote.choice}**`;
242
+ output += ` (confidence: ${vote.confidence}%)\n`;
243
+ if (vote.reasoning) {
244
+ output += ` šŸ’­ "${vote.reasoning}"\n`;
245
+ }
246
+ }
247
+ else {
248
+ output += `šŸ¦† **${vote.nickname}**: āŒ Invalid vote\n`;
249
+ }
250
+ output += `\n`;
251
+ }
252
+ output += `═══════════════════════════════════════\n`;
253
+ output += `šŸ“Š ${result.validVotes}/${result.totalVoters} valid votes\n`;
254
+ return output;
255
+ }
256
+ }
257
+ //# sourceMappingURL=consensus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consensus.js","sourceRoot":"","sources":["../../src/services/consensus.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { ProviderManager } from '../providers/manager.js';
2
+ import { DebateFormat } from '../config/types.js';
3
+ export interface DuckDebateArgs {
4
+ prompt: string;
5
+ rounds?: number;
6
+ providers?: string[];
7
+ format: DebateFormat;
8
+ synthesizer?: string;
9
+ }
10
+ export declare function duckDebateTool(providerManager: ProviderManager, args: Record<string, unknown>): Promise<{
11
+ content: {
12
+ type: string;
13
+ text: string;
14
+ }[];
15
+ }>;
16
+ //# sourceMappingURL=duck-debate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"duck-debate.d.ts","sourceRoot":"","sources":["../../src/tools/duck-debate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EACL,YAAY,EAKb,MAAM,oBAAoB,CAAC;AAG5B,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,YAAY,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAID,wBAAsB,cAAc,CAClC,eAAe,EAAE,eAAe,EAChC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;GAgH9B"}
@@ -0,0 +1,272 @@
1
+ import { logger } from '../utils/logger.js';
2
+ const DEFAULT_ROUNDS = 3;
3
+ export async function duckDebateTool(providerManager, args) {
4
+ const { prompt, rounds = DEFAULT_ROUNDS, providers, format, synthesizer, } = args;
5
+ // Validate inputs
6
+ if (!prompt || typeof prompt !== 'string') {
7
+ throw new Error('Prompt/topic is required');
8
+ }
9
+ if (!format || !['oxford', 'socratic', 'adversarial'].includes(format)) {
10
+ throw new Error('Format must be "oxford", "socratic", or "adversarial"');
11
+ }
12
+ if (rounds < 1 || rounds > 10) {
13
+ throw new Error('Rounds must be between 1 and 10');
14
+ }
15
+ // Get providers
16
+ const allProviders = providerManager.getProviderNames();
17
+ // If providers explicitly specified but less than 2, error
18
+ if (providers && providers.length < 2) {
19
+ throw new Error('At least 2 providers are required for a debate');
20
+ }
21
+ const debateProviders = providers && providers.length >= 2
22
+ ? providers
23
+ : allProviders;
24
+ if (debateProviders.length < 2) {
25
+ throw new Error('At least 2 providers are required for a debate');
26
+ }
27
+ // Validate providers exist
28
+ for (const p of debateProviders) {
29
+ if (!allProviders.includes(p)) {
30
+ throw new Error(`Provider "${p}" not found`);
31
+ }
32
+ }
33
+ logger.info(`Starting ${format} debate with ${debateProviders.length} participants for ${rounds} rounds`);
34
+ // Assign positions based on format
35
+ const participants = assignPositions(debateProviders, format, providerManager);
36
+ // Run debate rounds
37
+ const debateRounds = [];
38
+ for (let roundNum = 1; roundNum <= rounds; roundNum++) {
39
+ logger.info(`Debate round ${roundNum}/${rounds}`);
40
+ const roundArguments = [];
41
+ // Each participant argues in this round
42
+ for (const participant of participants) {
43
+ const argumentPrompt = buildArgumentPrompt(prompt, format, participant, roundNum, debateRounds, participants);
44
+ const response = await providerManager.askDuck(participant.provider, argumentPrompt);
45
+ roundArguments.push({
46
+ round: roundNum,
47
+ provider: participant.provider,
48
+ nickname: participant.nickname,
49
+ position: participant.position,
50
+ content: response.content,
51
+ timestamp: new Date(),
52
+ });
53
+ }
54
+ debateRounds.push(roundArguments);
55
+ }
56
+ // Generate synthesis
57
+ const synthesizerProvider = synthesizer || debateProviders[0];
58
+ const synthesisPrompt = buildSynthesisPrompt(prompt, format, debateRounds, participants);
59
+ const synthesisResponse = await providerManager.askDuck(synthesizerProvider, synthesisPrompt);
60
+ const result = {
61
+ topic: prompt,
62
+ format,
63
+ participants,
64
+ rounds: debateRounds,
65
+ synthesis: synthesisResponse.content,
66
+ synthesizer: synthesizerProvider,
67
+ totalRounds: rounds,
68
+ };
69
+ // Format output
70
+ const formattedOutput = formatDebateResult(result);
71
+ logger.info(`Debate completed: ${rounds} rounds, synthesized by ${synthesizerProvider}`);
72
+ return {
73
+ content: [
74
+ {
75
+ type: 'text',
76
+ text: formattedOutput,
77
+ },
78
+ ],
79
+ };
80
+ }
81
+ function assignPositions(providers, format, providerManager) {
82
+ const participants = [];
83
+ for (let i = 0; i < providers.length; i++) {
84
+ const provider = providers[i];
85
+ const providerInfo = providerManager.getProvider(provider);
86
+ let position;
87
+ if (format === 'oxford') {
88
+ // Oxford: alternating pro/con
89
+ position = i % 2 === 0 ? 'pro' : 'con';
90
+ }
91
+ else if (format === 'adversarial') {
92
+ // Adversarial: first is defender, rest are challengers (con)
93
+ position = i === 0 ? 'pro' : 'con';
94
+ }
95
+ else {
96
+ // Socratic: all neutral, questioning each other
97
+ position = 'neutral';
98
+ }
99
+ participants.push({
100
+ provider,
101
+ nickname: providerInfo.nickname,
102
+ position,
103
+ });
104
+ }
105
+ return participants;
106
+ }
107
+ function buildArgumentPrompt(topic, format, participant, round, previousRounds, allParticipants) {
108
+ const previousContext = buildPreviousContext(previousRounds);
109
+ if (format === 'oxford') {
110
+ return buildOxfordPrompt(topic, participant, round, previousContext);
111
+ }
112
+ else if (format === 'socratic') {
113
+ return buildSocraticPrompt(topic, participant, round, previousContext, allParticipants);
114
+ }
115
+ else {
116
+ return buildAdversarialPrompt(topic, participant, round, previousContext);
117
+ }
118
+ }
119
+ function buildPreviousContext(previousRounds) {
120
+ if (previousRounds.length === 0) {
121
+ return '';
122
+ }
123
+ let context = '\n\nPREVIOUS ARGUMENTS:\n';
124
+ for (const round of previousRounds) {
125
+ for (const arg of round) {
126
+ const posLabel = arg.position === 'pro' ? '[PRO]' :
127
+ arg.position === 'con' ? '[CON]' : '[NEUTRAL]';
128
+ context += `\n--- Round ${arg.round} - ${arg.nickname} ${posLabel} ---\n`;
129
+ context += `${arg.content}\n`;
130
+ }
131
+ }
132
+ return context;
133
+ }
134
+ function buildOxfordPrompt(topic, participant, round, previousContext) {
135
+ const position = participant.position === 'pro' ? 'IN FAVOR OF' : 'AGAINST';
136
+ const positionLabel = participant.position === 'pro' ? 'PRO' : 'CON';
137
+ return `You are participating in an Oxford-style debate.
138
+
139
+ TOPIC: "${topic}"
140
+
141
+ YOUR POSITION: ${position} (${positionLabel})
142
+ ROUND: ${round}
143
+
144
+ ${previousContext}
145
+
146
+ INSTRUCTIONS:
147
+ 1. Present clear, logical arguments ${position.toLowerCase()} the topic
148
+ 2. ${round > 1 ? 'Address and rebut opposing arguments from previous rounds' : 'Establish your core thesis and supporting points'}
149
+ 3. Use evidence, examples, and reasoning
150
+ 4. Be persuasive but intellectually honest
151
+ 5. Keep your argument focused and structured
152
+
153
+ Present your argument for Round ${round}:`;
154
+ }
155
+ function buildSocraticPrompt(topic, participant, round, previousContext, allParticipants) {
156
+ const otherParticipants = allParticipants
157
+ .filter(p => p.provider !== participant.provider)
158
+ .map(p => p.nickname)
159
+ .join(', ');
160
+ return `You are participating in a Socratic dialogue.
161
+
162
+ TOPIC: "${topic}"
163
+
164
+ YOUR ROLE: Philosophical inquirer exploring the topic through questions and reasoning
165
+ OTHER PARTICIPANTS: ${otherParticipants}
166
+ ROUND: ${round}
167
+
168
+ ${previousContext}
169
+
170
+ INSTRUCTIONS:
171
+ 1. ${round === 1 ? 'Begin by questioning assumptions about the topic' : 'Build on previous responses with deeper questions'}
172
+ 2. Use the Socratic method: ask probing questions that reveal underlying assumptions
173
+ 3. Offer your own perspective while remaining open to other views
174
+ 4. Seek to understand the truth through dialogue, not to "win"
175
+ 5. Challenge ideas respectfully and constructively
176
+
177
+ Present your contribution to Round ${round}:`;
178
+ }
179
+ function buildAdversarialPrompt(topic, participant, round, previousContext) {
180
+ const role = participant.position === 'pro' ? 'DEFENDER' : 'CHALLENGER';
181
+ const instruction = participant.position === 'pro'
182
+ ? 'Defend the proposition and address all critiques raised'
183
+ : 'Attack weaknesses in the arguments, find flaws, and present counter-examples';
184
+ return `You are participating in an adversarial debate.
185
+
186
+ TOPIC: "${topic}"
187
+
188
+ YOUR ROLE: ${role}
189
+ ROUND: ${round}
190
+
191
+ ${previousContext}
192
+
193
+ INSTRUCTIONS:
194
+ 1. ${instruction}
195
+ 2. Be rigorous and thorough in your analysis
196
+ 3. ${participant.position === 'con' ? 'Identify logical fallacies, weak evidence, or missing considerations' : 'Strengthen your position against attacks'}
197
+ 4. Use concrete examples and evidence
198
+ 5. Be intellectually aggressive but fair
199
+
200
+ Present your ${role.toLowerCase()} argument for Round ${round}:`;
201
+ }
202
+ function buildSynthesisPrompt(topic, format, rounds, participants) {
203
+ let transcript = '';
204
+ for (const round of rounds) {
205
+ for (const arg of round) {
206
+ const posLabel = arg.position === 'pro' ? '[PRO]' :
207
+ arg.position === 'con' ? '[CON]' : '[NEUTRAL]';
208
+ transcript += `\n--- Round ${arg.round} - ${arg.nickname} ${posLabel} ---\n`;
209
+ transcript += `${arg.content}\n`;
210
+ }
211
+ }
212
+ const participantList = participants
213
+ .map(p => `${p.nickname} (${p.position})`)
214
+ .join(', ');
215
+ return `You are the moderator synthesizing a ${format} debate.
216
+
217
+ TOPIC: "${topic}"
218
+ PARTICIPANTS: ${participantList}
219
+
220
+ DEBATE TRANSCRIPT:
221
+ ${transcript}
222
+
223
+ YOUR TASK:
224
+ 1. Summarize the key arguments from each side
225
+ 2. Identify the strongest points made
226
+ 3. Note where participants agreed or found common ground
227
+ 4. Highlight unresolved tensions or questions
228
+ 5. Provide a balanced conclusion (who had stronger arguments, or if it was a draw)
229
+ 6. Suggest what additional considerations might be valuable
230
+
231
+ Provide your synthesis:`;
232
+ }
233
+ function formatDebateResult(result) {
234
+ const formatEmoji = result.format === 'oxford' ? 'šŸŽ“' :
235
+ result.format === 'socratic' ? 'šŸ›ļø' : 'āš”ļø';
236
+ let output = `${formatEmoji} **${result.format.charAt(0).toUpperCase() + result.format.slice(1)} Debate**\n`;
237
+ output += `═══════════════════════════════════════\n\n`;
238
+ output += `**Topic:** "${result.topic}"\n`;
239
+ output += `**Format:** ${result.format}\n`;
240
+ output += `**Rounds:** ${result.totalRounds}\n\n`;
241
+ // Participants
242
+ output += `**Participants:**\n`;
243
+ for (const p of result.participants) {
244
+ const posEmoji = p.position === 'pro' ? 'āœ…' : p.position === 'con' ? 'āŒ' : 'šŸ”';
245
+ output += ` ${posEmoji} ${p.nickname} (${p.position})\n`;
246
+ }
247
+ output += `\n`;
248
+ // Debate rounds
249
+ output += `**Debate Transcript:**\n`;
250
+ output += `─────────────────────────────────────\n`;
251
+ for (let i = 0; i < result.rounds.length; i++) {
252
+ output += `\nšŸ“¢ **ROUND ${i + 1}**\n`;
253
+ for (const arg of result.rounds[i]) {
254
+ const posEmoji = arg.position === 'pro' ? 'āœ…' : arg.position === 'con' ? 'āŒ' : 'šŸ”';
255
+ output += `\n${posEmoji} **${arg.nickname}** [${arg.position.toUpperCase()}]:\n`;
256
+ // Truncate long arguments
257
+ const displayContent = arg.content.length > 800
258
+ ? arg.content.substring(0, 800) + '...[truncated]'
259
+ : arg.content;
260
+ output += `${displayContent}\n`;
261
+ }
262
+ }
263
+ // Synthesis
264
+ output += `\n═══════════════════════════════════════\n`;
265
+ output += `šŸŽÆ **Synthesis** (by ${result.synthesizer})\n`;
266
+ output += `─────────────────────────────────────\n`;
267
+ output += `${result.synthesis}\n`;
268
+ output += `\n═══════════════════════════════════════\n`;
269
+ output += `šŸ“Š ${result.totalRounds} rounds completed with ${result.participants.length} participants\n`;
270
+ return output;
271
+ }
272
+ //# sourceMappingURL=duck-debate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"duck-debate.js","sourceRoot":"","sources":["../../src/tools/duck-debate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { ProviderManager } from '../providers/manager.js';
2
+ export interface DuckIterateArgs {
3
+ prompt: string;
4
+ iterations?: number;
5
+ providers: [string, string];
6
+ mode: 'refine' | 'critique-improve';
7
+ }
8
+ export declare function duckIterateTool(providerManager: ProviderManager, args: Record<string, unknown>): Promise<{
9
+ content: {
10
+ type: string;
11
+ text: string;
12
+ }[];
13
+ }>;
14
+ //# sourceMappingURL=duck-iterate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"duck-iterate.d.ts","sourceRoot":"","sources":["../../src/tools/duck-iterate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAI1D,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,IAAI,EAAE,QAAQ,GAAG,kBAAkB,CAAC;CACrC;AAKD,wBAAsB,eAAe,CACnC,eAAe,EAAE,eAAe,EAChC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;GAkH9B"}