@rrr2010/opencode-roundtable 0.3.0 → 0.3.2

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 CHANGED
@@ -1,203 +1,244 @@
1
- # opencode-roundtable
2
-
3
- OpenCode plugin that orchestrates **multi-agent round-robin debates**.
4
- Agents with different personalities debate a topic turn by turn, sharing
5
- context while keeping their own system prompts and tools.
6
-
7
- A built-in observer automatically consolidates every debate into an
8
- executive summary.
9
-
10
- ## Installation
11
-
12
- ### npm (recommended)
13
-
14
- ```json
15
- {
16
- "plugin": ["@rrr2010/opencode-roundtable@latest"]
17
- }
18
- ```
19
-
20
- OpenCode auto-installs npm plugins on startup. No manual copy needed.
21
-
22
- ### Local (dev)
23
-
24
- ```bash
25
- git clone https://github.com/opencode-ai/roundtable
26
- cd roundtable
27
- bun run build
28
- npm link
29
- ```
30
-
31
- Then add `"@rrr2010/opencode-roundtable"` to your opencode.json `plugin` array.
32
- ```
33
-
34
- Add to `opencode.json` — OpenCode installs it with Bun on startup.
35
-
36
- ## Features
37
-
38
- - **Round-robin debate** — agents speak in sequence, each seeing the full discussion history
39
- - **Shared context** — tool outputs and discoveries are visible to all participants
40
- - **Built-in observer** — automatically consolidates the debate into an executive summary (overridable with a specific agent)
41
- - **Isolated session** — the debate runs in a child session, keeping the main session clean
42
- - **Extend mode** — continue a concluded roundtable with more rounds or a new topic
43
- - **Agent discovery** — `available_agents` tool helps the orchestrator know which agents exist
44
- - **Parallel roundtables** — multiple independent debates can run simultaneously
45
- - **User intervention** — the human can jump into the debate at any time
46
- - **Stuck session recovery** — if an extend is aborted mid-way, the next call auto-recovers
47
-
48
- ## Tool API
49
-
50
- ### `roundtable()`
51
-
52
- ```typescript
53
- roundtable({
54
- agents?: string[], // Names in speaking order (min 2). Required for new debates.
55
- prompt: string, // Topic or challenge. For multi-round, include per-round instructions.
56
- rounds?: number, // Complete rounds (default: 1, max: 50)
57
- observer?: string, // Agent for final consolidation (default: built-in)
58
- sessionID?: string, // ses_xxxx pass to extend a concluded debate
59
- title?: string, // Custom title (default: auto-generated from prompt)
60
- })
61
- ```
62
-
63
- **Returns:** `{ sessionID: string, summary: string }` after the debate concludes.
64
-
65
- **Side effect:** injects system-level prompts into each agent's context (role, topic, turn routing, lifecycle signals).
66
-
67
- ### `available_agents()`
68
-
69
- ```typescript
70
- available_agents()
71
- ```
72
-
73
- **Returns:** `"Available agents: pm, dev, rv, ..."` — a formatted string of agent names.
74
-
75
- ## Usage Examples
76
-
77
- ### Basic — one round, built-in observer
78
-
79
- ```typescript
80
- roundtable({
81
- agents: ["pm", "dev"],
82
- prompt: "What architecture should we use?",
83
- })
84
- ```
85
-
86
- ### Multi-round with per-round instructions
87
-
88
- ```typescript
89
- roundtable({
90
- agents: ["pm", "dev"],
91
- prompt: "Round 1: list pros. Round 2: list cons. Round 3: propose an implementation plan.",
92
- rounds: 3,
93
- })
94
- ```
95
-
96
- ### Explicit observer
97
-
98
- ```typescript
99
- roundtable({
100
- agents: ["pm", "dev"],
101
- prompt: "Should we migrate to microservices?",
102
- rounds: 2,
103
- observer: "rv",
104
- })
105
- ```
106
-
107
- ### Extend a concluded debate
108
-
109
- ```typescript
110
- roundtable({
111
- sessionID: "ses_abc123",
112
- rounds: 2,
113
- prompt: "Dive deeper into operational costs",
114
- })
115
- ```
116
-
117
- The session ID is injected into S1 as a noReply when the roundtable starts — check S1 context to find it.
118
-
119
- ### Discover agents first
120
-
121
- ```typescript
122
- const agents = available_agents()
123
- // agents => "Available agents: pm, dev, rv, build, plan"
124
- roundtable({
125
- agents: ["pm", "dev"],
126
- prompt: "...",
127
- })
128
- ```
129
-
130
- ## Configuration
131
-
132
- Place `~/.config/opencode/roundtable.json` to override defaults:
133
-
134
- ```json
135
- {
136
- "$schema": "https://raw.githubusercontent.com/opencode-ai/roundtable/main/docs/roundtable.schema.json",
137
- "defaultTimeoutMs": 300000,
138
- "loopSimilarityThreshold": 0.85,
139
- "toolOutputPreviewMax": 500,
140
- "maxRounds": 10,
141
- "defaultObserverPrompt": "You are an impartial roundtable observer..."
142
- }
143
- ```
144
-
145
- If the file doesn't exist, it's created automatically with defaults.
146
-
147
- ## Tips
148
-
149
- ### Agent selection
150
-
151
- Choose agents whose expertise matches the topic:
152
-
153
- | Agent | Best for |
154
- |-------|----------|
155
- | `pm` | Product decisions, strategy, trade-offs |
156
- | `dev` | Technical complexity, implementation effort |
157
- | `rv` | Code review, docs quality, inconsistency detection |
158
- | `plan` | Architecture planning, scope definition |
159
- | `build` | Implementation details, execution |
160
-
161
- ### Multi-round strategy
162
-
163
- For complex topics, structure rounds progressively:
164
-
165
- 1. **Round 1:** Explore each agent lists their perspective
166
- 2. **Round 2:** Challenge — agents critique each other's positions
167
- 3. **Round 3+:** Converge — propose concrete solutions
168
-
169
- Include all round instructions in the `prompt` parameter — all agents see the full agenda.
170
-
171
- ### Extend mode
172
-
173
- - Use the session ID from the S1 noReply message
174
- - Original topic is preserved; new prompt becomes the continuation
175
- - Agents must be the same as the original debate
176
- - Continue an extend for iterative refinement
177
-
178
- ## Agent colors (recommended)
179
-
180
- ```json
181
- {
182
- "agent": {
183
- "pm": { "color": "#3498db" },
184
- "dev": { "color": "#2ecc71" },
185
- "rv": { "color": "#e74c3c" },
186
- "plan": { "color": "#f39c12" },
187
- "build": { "color": "#9b59b6" }
188
- }
189
- }
190
- ```
191
-
192
- ## Documentation
193
-
194
- - [docs/SPEC.md](./docs/SPEC.md) Full technical specification
195
-
196
- ## Requirements
197
-
198
- - OpenCode (latest version)
199
- - No external dependencies
200
-
201
- ## License
202
-
203
- MIT
1
+ # opencode-roundtable
2
+
3
+ OpenCode plugin that orchestrates **multi-agent round-robin debates**.
4
+ Agents with different personalities debate a topic turn by turn, sharing
5
+ context while keeping their own system prompts and tools.
6
+
7
+ A built-in observer automatically consolidates every debate into an
8
+ executive summary.
9
+
10
+ ## Installation
11
+
12
+ ### npm (recommended)
13
+
14
+ ```json
15
+ {
16
+ "plugin": ["@rrr2010/opencode-roundtable@latest"]
17
+ }
18
+ ```
19
+
20
+ OpenCode auto-installs npm plugins on startup. No manual copy needed.
21
+
22
+ ### Local (dev)
23
+
24
+ ```bash
25
+ git clone https://github.com/opencode-ai/roundtable
26
+ cd roundtable
27
+ bun run build
28
+ npm link
29
+ ```
30
+
31
+ Then add `"@rrr2010/opencode-roundtable"` to your opencode.json `plugin` array.
32
+
33
+ ## Features
34
+
35
+ - **Round-robin debate** — agents speak in sequence, each seeing the full discussion history
36
+ - **Shared context** — tool outputs and discoveries are visible to all participants
37
+ - **Built-in observer** — automatically consolidates the debate into an executive summary (overridable with a specific agent)
38
+ - **Isolated session** — the debate runs in a child session, keeping the main session clean
39
+ - **File persistence** — state stored on disk, survives restarts
40
+ - **Extend mode** — continue a concluded roundtable with more rounds or a new topic
41
+ - **Agent discovery** — `available_agents` tool helps the orchestrator know which agents exist
42
+ - **Active roundtables** — `active_roundtables` tool lists current debates with status
43
+ - **TUI plugin** — badge `[RT]`, `← Back` link, `/roundtables` command
44
+ - **Auto-navigate** — optional auto-navigation between sessions on create/conclude
45
+ - **Parallel roundtables** — multiple independent debates can run simultaneously
46
+ - **User intervention** — the human can jump into the debate at any time
47
+ - **Loop detection** — Jaccard bigram similarity detects agent impasses early
48
+
49
+ ## Tool API
50
+
51
+ ### `roundtable()`
52
+
53
+ ```typescript
54
+ roundtable({
55
+ agents?: string[], // Names in speaking order (min 2). Required for new debates.
56
+ prompt: string, // Topic or challenge. For multi-round, include per-round instructions.
57
+ rounds?: number, // Complete rounds (default: 1, max: 50)
58
+ observer?: string, // Agent for final consolidation (default: built-in)
59
+ sessionID?: string, // ses_xxxx pass to extend a concluded debate
60
+ title?: string, // Custom title (default: auto-generated from prompt)
61
+ observerPrompt?: string, // Override the observer consolidation prompt (e.g., "Save a detailed report to report.md")
62
+ })
63
+ ```
64
+
65
+ **Returns:** `{ sessionID: string, summary: string }` after the debate concludes.
66
+
67
+ **Side effect:** injects system-level prompts into each agent's context during
68
+ the debate (role-setting, topic, turn routing, and lifecycle signals).
69
+
70
+ ### `available_agents()`
71
+
72
+ ```typescript
73
+ available_agents()
74
+ ```
75
+
76
+ **Returns:** `"Available agents: pm, dev, rv, ..."` — a formatted string of agent names.
77
+
78
+ ### `active_roundtables()`
79
+
80
+ ```typescript
81
+ active_roundtables()
82
+ ```
83
+
84
+ **Returns:** clickable session listings with status, e.g.:
85
+ ```
86
+ Active roundtables:
87
+ - #ses_xxx · pm→dev→rv (R1/2) · debating
88
+ - #ses_yyy · pm→dev (R2/2) · consolidating
89
+ ```
90
+
91
+ ## Usage Examples
92
+
93
+ ### Basic — one round, built-in observer
94
+
95
+ ```typescript
96
+ roundtable({
97
+ agents: ["pm", "dev"],
98
+ prompt: "What architecture should we use?",
99
+ })
100
+ ```
101
+
102
+ ### Multi-round with per-round instructions
103
+
104
+ ```typescript
105
+ roundtable({
106
+ agents: ["pm", "dev"],
107
+ prompt: "Round 1: list pros. Round 2: list cons. Round 3: propose an implementation plan.",
108
+ rounds: 3,
109
+ })
110
+ ```
111
+
112
+ ### Explicit observer
113
+
114
+ ```typescript
115
+ roundtable({
116
+ agents: ["pm", "dev"],
117
+ prompt: "Should we migrate to microservices?",
118
+ rounds: 2,
119
+ observer: "rv",
120
+ })
121
+ ```
122
+
123
+ ### Extend a concluded debate
124
+
125
+ ```typescript
126
+ roundtable({
127
+ sessionID: "ses_abc123",
128
+ rounds: 2,
129
+ prompt: "Dive deeper into operational costs",
130
+ })
131
+ ```
132
+
133
+ The session ID is shown in the S1 noReply message when the roundtable
134
+ starts — check S1 context to find it.
135
+
136
+ ### Discover agents first
137
+
138
+ ```typescript
139
+ const agents = available_agents()
140
+ // agents => "Available agents: pm, dev, rv, build, plan"
141
+ roundtable({
142
+ agents: ["pm", "dev"],
143
+ prompt: "...",
144
+ })
145
+ ```
146
+
147
+ ### List active roundtables
148
+
149
+ ```typescript
150
+ const active = active_roundtables()
151
+ // active => "Active roundtables:\n- #ses_xxx · pm→dev (R1/2) · debating"
152
+ ```
153
+
154
+ ## Configuration
155
+
156
+ Place `~/.config/opencode/roundtable.json` to override defaults:
157
+
158
+ ```json
159
+ {
160
+ "$schema": "https://raw.githubusercontent.com/opencode-ai/roundtable/main/docs/roundtable.schema.json",
161
+ "defaultTimeoutMs": 300000,
162
+ "loopSimilarityThreshold": 0.85,
163
+ "toolOutputPreviewMax": 500,
164
+ "maxRounds": 10,
165
+ "defaultObserverPrompt": "You are an impartial roundtable observer...",
166
+ "navigation": "link"
167
+ }
168
+ ```
169
+
170
+ If the file doesn't exist, it's created automatically with defaults.
171
+
172
+ ### Navigation modes
173
+
174
+ | Value | Behavior |
175
+ |-------|----------|
176
+ | `"link"` (default) | No auto-navigation. Relies on native `#ses_xxx` link rendering |
177
+ | `"auto"` | Auto-navigates S1→S2 on create, S2→S1 on conclude |
178
+ | `"none"` | No automatic navigation |
179
+
180
+ ### TUI Features
181
+
182
+ The plugin registers a TUI component that provides:
183
+
184
+ - **`[RT]` badge** — shown in the sidebar for roundtable sessions
185
+ - **`← Back` link** — clickable link on child sessions, navigates to parent
186
+ - **`/roundtables` command** slash command opens a dialog with clickable session list
187
+
188
+ ## Tips
189
+
190
+ ### Agent selection
191
+
192
+ Choose agents whose expertise matches the topic:
193
+
194
+ | Agent | Best for |
195
+ |-------|----------|
196
+ | `pm` | Product decisions, strategy, trade-offs |
197
+ | `dev` | Technical complexity, implementation effort |
198
+ | `rv` | Code review, docs quality, inconsistency detection |
199
+ | `plan` | Architecture planning, scope definition |
200
+ | `build` | Implementation details, execution |
201
+
202
+ ### Multi-round strategy
203
+
204
+ For complex topics, structure rounds progressively:
205
+
206
+ 1. **Round 1:** Explore — each agent lists their perspective
207
+ 2. **Round 2:** Challenge — agents critique each other's positions
208
+ 3. **Round 3+:** Converge — propose concrete solutions
209
+
210
+ Include all round instructions in the `prompt` parameter — all agents see the full agenda.
211
+
212
+ ### Extend mode
213
+
214
+ - Use the session ID from the S1 noReply message when the roundtable starts
215
+ - Original topic is preserved; new prompt becomes the continuation
216
+ - Agents must be the same as the original debate (validated)
217
+ - Continue an extend for iterative refinement
218
+
219
+ ## Agent colors (recommended)
220
+
221
+ ```json
222
+ {
223
+ "agent": {
224
+ "pm": { "color": "#3498db" },
225
+ "dev": { "color": "#2ecc71" },
226
+ "rv": { "color": "#e74c3c" },
227
+ "plan": { "color": "#f39c12" },
228
+ "build": { "color": "#9b59b6" }
229
+ }
230
+ }
231
+ ```
232
+
233
+ ## Documentation
234
+
235
+ - [docs/SPEC.md](./docs/SPEC.md) — Full technical specification
236
+
237
+ ## Requirements
238
+
239
+ - OpenCode (latest version)
240
+ - No external dependencies
241
+
242
+ ## License
243
+
244
+ MIT
package/dist/index.js CHANGED
@@ -28,7 +28,8 @@ var DEFAULT_CONFIG = {
28
28
  "5. **Suggested next steps**"
29
29
  ].join(`
30
30
  `),
31
- maxRounds: 10
31
+ maxRounds: 10,
32
+ navigation: "link"
32
33
  };
33
34
  var config = { ...DEFAULT_CONFIG };
34
35
  function getConfig() {
@@ -40,7 +41,8 @@ function validateConfig(raw) {
40
41
  loopSimilarityThreshold: typeof raw.loopSimilarityThreshold === "number" && raw.loopSimilarityThreshold >= 0 && raw.loopSimilarityThreshold <= 1 ? raw.loopSimilarityThreshold : DEFAULT_CONFIG.loopSimilarityThreshold,
41
42
  toolOutputPreviewMax: typeof raw.toolOutputPreviewMax === "number" && raw.toolOutputPreviewMax >= 100 ? raw.toolOutputPreviewMax : DEFAULT_CONFIG.toolOutputPreviewMax,
42
43
  defaultObserverPrompt: typeof raw.defaultObserverPrompt === "string" && raw.defaultObserverPrompt.length > 0 ? raw.defaultObserverPrompt : DEFAULT_CONFIG.defaultObserverPrompt,
43
- maxRounds: typeof raw.maxRounds === "number" && raw.maxRounds >= 1 ? raw.maxRounds : DEFAULT_CONFIG.maxRounds
44
+ maxRounds: typeof raw.maxRounds === "number" && raw.maxRounds >= 1 ? raw.maxRounds : DEFAULT_CONFIG.maxRounds,
45
+ navigation: raw.navigation === "selectSession" || raw.navigation === "none" || raw.navigation === "auto" ? raw.navigation : DEFAULT_CONFIG.navigation
44
46
  };
45
47
  }
46
48
  async function loadConfig(ctx) {
@@ -335,6 +337,23 @@ Continuation: ${extendPrompt}`;
335
337
  ].join(`
336
338
  `);
337
339
  }
340
+ async function navigateToSession(ctx, targetID, _parentID) {
341
+ try {
342
+ if (typeof ctx.client.tui.selectSession === "function") {
343
+ await ctx.client.tui.selectSession({ sessionID: targetID });
344
+ return true;
345
+ }
346
+ await ctx.client.tui.publish({
347
+ body: {
348
+ type: "tui.session.select",
349
+ properties: { sessionID: targetID }
350
+ }
351
+ });
352
+ return true;
353
+ } catch {
354
+ return false;
355
+ }
356
+ }
338
357
  async function scanOrphanRoundtables(ctx) {
339
358
  const sessionIDs = await listStateFiles();
340
359
  let loaded = 0;
@@ -380,11 +399,11 @@ function buildAgentPrompt(state, agent) {
380
399
  `);
381
400
  }
382
401
  function buildObserverPrompt(state, observer) {
383
- const observerPrompt = getConfig().defaultObserverPrompt;
402
+ const observerPrompt = state.observerPrompt ?? getConfig().defaultObserverPrompt;
384
403
  if (observer === "built-in")
385
404
  return observerPrompt;
386
405
  return `You are an impartial roundtable observer.
387
- ` + `Your role: ${observer}. Provide an executive summary of the debate.
406
+ ` + `Your role: ${observer}.
388
407
 
389
408
  ` + observerPrompt;
390
409
  }
@@ -393,7 +412,10 @@ function buildObserverPrompt(state, observer) {
393
412
  async function startNewRoundtable(ctx, args, toolCtx) {
394
413
  const agents = args.agents;
395
414
  const newSession = await ctx.client.session.create({
396
- body: { title: generateDefaultTitle({ ...args, agents }) }
415
+ body: {
416
+ title: generateDefaultTitle({ ...args, agents }),
417
+ parentID: toolCtx.sessionID
418
+ }
397
419
  });
398
420
  const sessionID = newSession.data.id;
399
421
  const parentSessionID = toolCtx.sessionID;
@@ -411,7 +433,8 @@ async function startNewRoundtable(ctx, args, toolCtx) {
411
433
  errors: [],
412
434
  createdAt: Date.now(),
413
435
  currentGeneration: 0,
414
- userInterjections: []
436
+ userInterjections: [],
437
+ observerPrompt: args.observerPrompt
415
438
  };
416
439
  states.set(sessionID, state);
417
440
  try {
@@ -423,10 +446,20 @@ async function startNewRoundtable(ctx, args, toolCtx) {
423
446
  noReply: true,
424
447
  parts: [{
425
448
  type: "text",
426
- text: `The roundtable has started (agents: ${agents.join(", ")}, ${args.rounds} round(s)). To extend it later, use the tool roundtable({sessionID: "${sessionID}", rounds: N, prompt: "..."})`
449
+ text: `⚙ Roundtable started #${sessionID} • ${agents.join(" ")} ${args.rounds} round(s)`
427
450
  }]
428
451
  }
429
452
  });
453
+ await ctx.client.session.prompt({
454
+ path: { id: sessionID },
455
+ body: {
456
+ noReply: true,
457
+ parts: [{ type: "text", text: `⚙ Parent: #${parentSessionID}` }]
458
+ }
459
+ });
460
+ if (getConfig().navigation === "auto") {
461
+ await navigateToSession(ctx, sessionID, parentSessionID);
462
+ }
430
463
  await ctx.client.tui.showToast({
431
464
  body: {
432
465
  message: `Roundtable started in #${sessionID} (${agents.join(" → ")} · ${args.rounds} round(s))`,
@@ -484,10 +517,13 @@ async function sendToAgent(ctx, state) {
484
517
  }
485
518
  }
486
519
  async function updateSessionTitle(ctx, state) {
487
- const summary = state.prompt.length > 60 ? state.prompt.slice(0, 57) + "..." : state.prompt;
520
+ const summary = state.prompt.length > 40 ? state.prompt.slice(0, 37) + "..." : state.prompt;
521
+ const agentList = state.agents.join("→");
522
+ const roundInfo = `R${state.currentRound + 1}/${state.totalRounds}`;
523
+ const title = `⚡ "${summary}" · ${agentList} (${roundInfo} · ↑ #${state.parentSessionID})`;
488
524
  await ctx.client.session.update({
489
525
  path: { id: state.sessionID },
490
- body: { title: `(Roundtable) - ${summary}` }
526
+ body: { title }
491
527
  });
492
528
  }
493
529
  async function sendObserverPrompt(ctx, state) {
@@ -533,14 +569,17 @@ async function finalizeRoundtable(ctx, state) {
533
569
  pendingResults.delete(sessionID);
534
570
  }
535
571
  await injectRoundtableDelimiter(ctx, sessionID);
536
- const shortPrompt = state.prompt.length > 50 ? state.prompt.slice(0, 47) + "..." : state.prompt;
572
+ const shortPrompt = state.prompt.length > 40 ? state.prompt.slice(0, 37) + "..." : state.prompt;
537
573
  await ctx.client.session.update({
538
574
  path: { id: sessionID },
539
- body: { title: `(Roundtable) - ${shortPrompt} · CONCLUDED` }
575
+ body: { title: `⚡ "${shortPrompt}" · ${state.agents.join("→")} ✓` }
540
576
  });
541
577
  try {
542
578
  await saveStateFile(state);
543
579
  } catch {}
580
+ if (getConfig().navigation === "auto") {
581
+ await navigateToSession(ctx, state.parentSessionID, sessionID);
582
+ }
544
583
  await ctx.client.tui.showToast({
545
584
  body: { message: "Roundtable concluded", variant: "success" }
546
585
  });
@@ -845,7 +884,8 @@ async function extendRoundtable(ctx, args, _toolCtx) {
845
884
  errors: [...originalState.errors],
846
885
  createdAt: Date.now(),
847
886
  currentGeneration: 0,
848
- userInterjections: [...originalState.userInterjections ?? []]
887
+ userInterjections: [...originalState.userInterjections ?? []],
888
+ observerPrompt: args.observerPrompt ?? originalState.observerPrompt
849
889
  };
850
890
  states.set(sessionID, newState);
851
891
  try {
@@ -861,7 +901,7 @@ async function extendRoundtable(ctx, args, _toolCtx) {
861
901
  noReply: true,
862
902
  parts: [{
863
903
  type: "text",
864
- text: `The roundtable has been extended (${args.rounds} more round(s)). To extend again, use the tool roundtable({sessionID: "${sessionID}", rounds: N, prompt: "..."})`
904
+ text: `⚙ Roundtable extended #${sessionID} • +${args.rounds} round(s)`
865
905
  }]
866
906
  }
867
907
  });
@@ -945,7 +985,8 @@ var RoundtablePlugin = async (ctx) => {
945
985
  rounds: tool.schema.number().min(1).max(50).describe("Number of complete rounds (each round = all agents speak once). " + "Default: 1. Max: 50. For complex topics with 2+ rounds, include per-round focus " + "instructions in the prompt parameter so all agents see the agenda."),
946
986
  observer: tool.schema.string().optional().describe("Agent name for final consolidation. The observer does not debate — it " + "summarizes after all rounds. Omit to use the built-in observer."),
947
987
  sessionID: tool.schema.string().optional().describe("Session ID (format: ses_xxxx) from a previous roundtable call to " + "continue a concluded debate. Omit this parameter and pass agents + " + "prompt to start a fresh debate."),
948
- title: tool.schema.string().optional().describe("Custom title for the session (max 200 chars). If omitted, auto-generated " + 'as "(Roundtable) - {first 80 chars of prompt, truncated at word boundary}".')
988
+ title: tool.schema.string().optional().describe("Custom title for the session (max 200 chars). If omitted, auto-generated " + 'as "(Roundtable) - {first 80 chars of prompt, truncated at word boundary}".'),
989
+ observerPrompt: tool.schema.string().optional().describe("Override the default observer consolidation prompt. Use this to control " + "the format and focus of the final summary — e.g., ask the observer to " + "save a detailed report to file, focus on technical decisions only, " + "output as JSON, extract action items, etc. " + "If omitted, the default observer prompt is used (executive summary).")
949
990
  },
950
991
  async execute(args, toolCtx) {
951
992
  try {
@@ -1002,6 +1043,22 @@ var RoundtablePlugin = async (ctx) => {
1002
1043
  return "Error: Could not fetch agent list. The server might not be ready.";
1003
1044
  }
1004
1045
  }
1046
+ }),
1047
+ active_roundtables: tool({
1048
+ description: "Lists all active roundtables with their status. " + "Each entry shows session ID, agents, current round, and phase. " + "Returns clickable session IDs that can be used to navigate.",
1049
+ args: {},
1050
+ async execute() {
1051
+ const active = [];
1052
+ for (const [sid, s] of states) {
1053
+ const status = s.phase === "active" ? "debating" : s.phase === "observing" ? "consolidating" : s.phase === "done" ? "concluded" : s.phase;
1054
+ active.push(`- #${sid} · ${s.agents.join("→")} (R${s.currentRound + 1}/${s.totalRounds}) · ${status}`);
1055
+ }
1056
+ if (active.length === 0)
1057
+ return "No active roundtables.";
1058
+ return `Active roundtables:
1059
+ ${active.join(`
1060
+ `)}`;
1061
+ }
1005
1062
  })
1006
1063
  }
1007
1064
  };
@@ -1010,5 +1067,5 @@ export {
1010
1067
  RoundtablePlugin
1011
1068
  };
1012
1069
 
1013
- //# debugId=BEEF18A38922C86164756E2164756E21
1070
+ //# debugId=C8BED17810CFAA4D64756E2164756E21
1014
1071
  //# sourceMappingURL=index.js.map