import{EventEmitter as e}from"node:events";var t=class extends e{#e;#t=new Map;#n=[];#r=`idle`;#i=`auto`;#a;#o=null;#s=null;#c=null;#l=null;#u=null;constructor(e,t){super(),this.#e=e,this.#a={strategy:`random`,timeoutMs:3e4,maxErrors:3,thinkingTimeMs:1e3,...t}}addParticipant(e){if(this.#t.has(e.id))throw Error(`Participant id "${e.id}" already exists.`);if(e.model&&Array.from(this.#t.values()).some(t=>t.model===e.model))throw Error(`Model "${e.model}" is already participating.`);let t={...e,errorCount:0};this.#t.set(e.id,t),this.emit(`participants-updated`,Array.from(this.#t.values())),this.#_(`${t.name} joined the discussion.`),this.#r===`discussing`&&this.#i===`auto`&&!this.#o&&this.#d()}removeParticipant(e){let t=this.#t.get(e);if(!t)return;let n=this.#o===e;this.#t.delete(e),this.#s===e&&(this.#s=null),this.emit(`participants-updated`,Array.from(this.#t.values())),this.#_(`${t.name} left the discussion.`),n?this.#y():this.#r===`discussing`&&this.#i===`auto`&&!this.#o&&this.#d()}get participants(){return Array.from(this.#t.values())}get history(){return[...this.#n]}get currentMessage(){return this.#c?{...this.#c}:null}get status(){return this.#r}get mode(){return this.#i}get topic(){return this.#a.topic}get currentSpeakerId(){return this.#o}setMode(e){this.#i=e,this.emit(`mode-changed`,e),e===`manual`&&this.#v(),e===`auto`&&this.#r===`discussing`&&!this.#o&&this.#d()}updateConfig(e){this.#a={...this.#a,...e}}start(){if(this.#r!==`idle`)return;this.#r=`discussing`,this.#s=null,this.emit(`status-changed`,this.#r);let e={id:crypto.randomUUID(),role:`system`,content:`Topic: ${this.#a.topic}\nParticipants: ${this.participants.map(e=>`${e.name} (${e.type})`).join(`, `)}`,senderId:`system`,timestamp:Date.now()};this.#g(e),this.#i===`auto`&&this.#d()}pause(){this.#r!==`idle`&&(this.#r=`paused`,this.#v(),this.emit(`status-changed`,this.#r))}resume(){this.#r===`paused`&&(this.#r=`discussing`,this.emit(`status-changed`,this.#r),this.#i===`auto`&&!this.#o&&this.#d())}stop(){this.#r=`idle`,this.#v(),this.#y({skipReschedule:!0}),this.#s=null,this.emit(`status-changed`,this.#r)}interrupt(){this.#o&&this.#y()}reset(){this.stop(),this.#n=[],this.#c=null,this.#s=null,this.emit(`history-cleared`),this.emit(`participants-updated`,Array.from(this.#t.values()))}async injectMessage(e,t){let n=this.#t.get(e);if(!n)throw Error(`Participant not found`);let r={id:crypto.randomUUID(),role:n.type===`human`?`user`:`assistant`,content:t,senderId:e,timestamp:Date.now()};this.#g(r),this.#r===`discussing`&&this.#i===`auto`&&!this.#o&&this.#d()}setNextSpeaker(e){if(!(this.#r!==`discussing`&&this.#r!==`paused`)){if(this.#v(),this.#o&&this.#o!==e)this.#y();else if(this.#o===e)return;this.#r===`paused`&&(this.#r=`discussing`,this.emit(`status-changed`,this.#r)),this.#p(e)}}async generateSummary(e){let t=this.#t.get(e);if(!t||!t.model)throw Error(`Invalid summarizer`);let n={messages:[{role:`user`,content:`Please summarize the discussion so far on the topic "${this.#a.topic}".
    
Discussion History:
${this.#h()}

Provide a concise summary of the key points and conclusions.`}],model:t.model};return(await this.#e.execute(n)).content}#d(){this.#v(),!(this.#r!==`discussing`||this.#i!==`auto`)&&(this.#u=setTimeout(()=>{let e=this.#f();e&&this.#p(e)},this.#a.thinkingTimeMs))}#f(){let e=this.participants.filter(e=>e.type===`ai`);if(e.length===0)return null;let t=e.map(e=>e.id),n=this.#n[this.#n.length-1],r=n&&t.includes(n.senderId)?n.senderId:null,i=this.#s??r,a=e.length>1&&i?e.filter(e=>e.id!==i):e;return a.length===0?e[0].id:this.#a.strategy===`random`?a[Math.floor(Math.random()*a.length)].id:t[((i?t.indexOf(i):-1)+1)%t.length]}async#p(e){let t=this.#t.get(e);if(!t||t.type!==`ai`||!t.model)return;this.#o=e,this.#s=e,this.#r=`speaking`,this.emit(`status-changed`,this.#r),this.emit(`turn-start`,e),this.#l=new AbortController;let n=this.#l,r=crypto.randomUUID(),i=Date.now(),a=``,o={id:r,role:`assistant`,content:``,senderId:e,timestamp:i};this.#c=o,this.emit(`message`,o);try{let o={messages:[{role:`user`,content:this.#m(t)}],model:t.model,stream:!0,abortSignal:n.signal},s=this.#e.executeStream(o),c=new Promise((e,t)=>{setTimeout(()=>t(Error(`Timeout`)),this.#a.timeoutMs)}),l=await Promise.race([s,c]);for await(let e of l.textStream){if(n.signal.aborted)break;a+=e,this.#c&&(this.#c.content=a),this.emit(`message-chunk`,{id:r,delta:e,content:a})}n.signal.aborted||(this.#g({id:r,role:`assistant`,content:a,senderId:e,timestamp:i}),t.errorCount=0)}catch(n){console.error(`Error in turn for ${t.name}:`,n),t.errorCount++,this.emit(`error`,{participantId:e,error:n.message}),t.errorCount>this.#a.maxErrors&&(this.emit(`participant-dropped`,e),this.removeParticipant(e))}finally{this.#o===e&&(this.#o=null),this.#c&&this.#c.id===r&&(this.#c=null),this.#l===n&&(this.#l=null),!this.#o&&this.#r===`speaking`&&(this.#r=`discussing`,this.emit(`status-changed`,this.#r)),this.#i===`auto`&&this.#r===`discussing`&&!this.#o&&this.#d()}}#m(e){let t=this.participants.map(e=>`${e.name}${e.model?` (${e.model})`:``}`).join(`, `);return`You are ${e.name} in a group discussion.
Topic: "${this.#a.topic}"
Active participants: ${t}

Instructions:
1. Speak naturally as your character.
2. Keep responses concise (1-3 paragraphs).
3. If you want to refer to a specific person, use @Name (e.g., @Claude) and acknowledge any new arrivals.
4. Do not repeat yourself or others excessively.
5. Advance the conversation with new insights or questions.

Conversation History:
${this.#h()}

Respond now as ${e.name}:`}#h(){return this.#n.slice(-20).map(e=>{let t=this.#t.get(e.senderId);return`[${t?t.name:e.role===`system`?`System`:`Unknown`}]: ${e.content}`}).join(`

`)}#g(e){this.#n.push(e),this.emit(`message`,e)}#_(e){let t={id:crypto.randomUUID(),role:`system`,content:e,senderId:`system`,timestamp:Date.now()};this.#g(t)}#v(){this.#u&&=(clearTimeout(this.#u),null)}#y(e){this.#l&&=(this.#l.abort(),null);let t=!!this.#o;this.#o=null,this.#c=null,t&&this.#r===`speaking`&&(this.#r=`discussing`,this.emit(`status-changed`,this.#r)),!e?.skipReschedule&&this.#i===`auto`&&this.#r===`discussing`&&this.#d()}};export{t};