--- tags: - gradio-custom-component - custom-component-track - roundtable - consilium title: gradio_consilium_roundtable short_description: The roundtable for artificial minds colorFrom: blue colorTo: yellow sdk: gradio pinned: false app_file: space.py emoji: šŸ† --- # `gradio_consilium_roundtable` PyPI - Version The roundtable for artificial minds ## Installation ```bash pip install gradio_consilium_roundtable ``` ## Usage ```python import gradio as gr from gradio_consilium_roundtable import consilium_roundtable import json def simulate_discussion(): """Simulate a live AI discussion with custom avatar images""" # Define avatar images (you can replace these URLs with actual image URLs) avatar_images = { "QwQ-32B": "https://cdn-avatars.huggingface.co/v1/production/uploads/620760a26e3b7210c2ff1943/-s1gyJfvbE1RgO5iBeNOi.png", "DeepSeek-R1": "https://logosandtypes.com/wp-content/uploads/2025/02/deepseek.svg", "Mistral Large": "https://logosandtypes.com/wp-content/uploads/2025/02/mistral-ai.svg", "Claude": "https://claude.ai/favicon.ico", # Web Search Agent will use emoji fallback (no image provided) } # Initial state - everyone ready initial_state = { "participants": ["QwQ-32B", "DeepSeek-R1", "Mistral Large", "Claude", "Web Search Agent"], "messages": [], "currentSpeaker": None, "thinking": [], "showBubbles": [], "avatarImages": avatar_images } states = [ # 1. QwQ-32B starts thinking { "participants": ["QwQ-32B", "DeepSeek-R1", "Mistral Large", "Claude", "Web Search Agent"], "messages": [], "currentSpeaker": None, "thinking": ["QwQ-32B"], "showBubbles": [], "avatarImages": avatar_images }, # 2. DeepSeek-R1 and Search start thinking - QwQ-32B's bubble should stay visible { "participants": ["QwQ-32B", "DeepSeek-R1", "Mistral Large", "Claude", "Web Search Agent"], "messages": [ {"speaker": "QwQ-32B", "text": "This is a very long response that should demonstrate the scrolling functionality. I'm going to explain multiple points in detail.\n\n**Key Analysis Points:**\n- First consideration: market dynamics\n- Second factor: technical feasibility\n- Third aspect: resource allocation\n\nWe need to evaluate each of these systematically."} ], "currentSpeaker": None, "thinking": ["DeepSeek-R1", "Web Search Agent"], "showBubbles": ["QwQ-32B"], "avatarImages": avatar_images }, # 3. DeepSeek-R1 responds - both QwQ-32B and DeepSeek-R1 bubbles visible { "participants": ["QwQ-32B", "DeepSeek-R1", "Mistral Large", "Claude", "Web Search Agent"], "messages": [ {"speaker": "QwQ-32B", "text": "Here's my detailed analysis:\n\n**Key Points:**\n- Market dynamics are shifting rapidly\n- Technical feasibility looks promising\n- Resource allocation needs careful planning\n\n`Implementation roadmap` should include phased rollout."}, {"speaker": "DeepSeek-R1", "text": "Excellent foundation, QwQ-32B! I'd like to add some **quantitative analysis** to your reasoning:\n\n> Statistical models suggest a 73% success probability\n\nLet me run some deeper calculations..."} ], "currentSpeaker": "DeepSeek-R1", "thinking": [], "showBubbles": ["QwQ-32B"], "avatarImages": avatar_images }, # 4. Multiple models thinking - previous responses stay visible { "participants": ["QwQ-32B", "DeepSeek-R1", "Mistral Large", "Claude", "Web Search Agent"], "messages": [ {"speaker": "QwQ-32B", "text": "Here's my detailed analysis with key considerations for our strategic approach."}, {"speaker": "DeepSeek-R1", "text": "Excellent foundation! Statistical models suggest a 73% success probability based on current market conditions."} ], "currentSpeaker": None, "thinking": ["Mistral Large", "Claude"], "showBubbles": ["QwQ-32B", "DeepSeek-R1"], "avatarImages": avatar_images }, # 5. Search agent responds with data - all previous responses visible { "participants": ["QwQ-32B", "DeepSeek-R1", "Mistral Large", "Claude", "Web Search Agent"], "messages": [ {"speaker": "QwQ-32B", "text": "Here's my detailed analysis with key considerations for our strategic approach."}, {"speaker": "DeepSeek-R1", "text": "Excellent foundation! Statistical models suggest a 73% success probability based on current market conditions."}, {"speaker": "Web Search Agent", "text": "šŸ“Š **Recent Market Data:**\n\n- Industry growth: +23% YoY\n- Competition analysis: 5 major players\n- Consumer sentiment: 87% positive\n\nSources: MarketWatch, TechCrunch, Industry Reports"} ], "currentSpeaker": "Web Search Agent", "thinking": [], "showBubbles": ["QwQ-32B", "DeepSeek-R1"], "avatarImages": avatar_images }, # 6. Claude joins the discussion { "participants": ["QwQ-32B", "DeepSeek-R1", "Mistral Large", "Claude", "Web Search Agent"], "messages": [ {"speaker": "QwQ-32B", "text": "Here's my detailed analysis with key considerations for our strategic approach."}, {"speaker": "DeepSeek-R1", "text": "Statistical models suggest a 73% success probability based on current market conditions."}, {"speaker": "Web Search Agent", "text": "šŸ“Š Industry growth: +23% YoY, Competition: 5 major players, Consumer sentiment: 87% positive"}, {"speaker": "Claude", "text": "Great insights everyone! Let me synthesize this information:\n\nšŸŽÆ **Strategic Recommendation:**\nBased on the quantitative analysis and market data, I suggest a **phased approach** with risk mitigation strategies built in."} ], "currentSpeaker": "Claude", "thinking": [], "showBubbles": ["QwQ-32B", "DeepSeek-R1", "Web Search Agent"], "avatarImages": avatar_images }, # 7. Final consensus with Mistral Large { "participants": ["QwQ-32B", "DeepSeek-R1", "Mistral Large", "Claude", "Web Search Agent"], "messages": [ {"speaker": "QwQ-32B", "text": "Strategic analysis complete with key considerations outlined."}, {"speaker": "DeepSeek-R1", "text": "Statistical validation: 73% success probability confirmed."}, {"speaker": "Web Search Agent", "text": "Market data supports positive outlook: +23% growth, 87% sentiment."}, {"speaker": "Claude", "text": "Phased approach recommended with integrated risk mitigation."}, {"speaker": "Mistral Large", "text": "šŸ† **CONSENSUS ACHIEVED**\n\nAll analyses converge on a **GO decision** with the following framework:\n\nāœ… Phased implementation\nāœ… 73% success probability\nāœ… Strong market fundamentals\nāœ… Risk mitigation protocols"} ], "currentSpeaker": "Mistral Large", "thinking": [], "showBubbles": ["QwQ-32B", "DeepSeek-R1", "Web Search Agent", "Claude"], "avatarImages": avatar_images } ] return initial_state, states def update_discussion_state(state_index, states): """Get the next state in the discussion""" if state_index >= len(states): state_index = 0 return states[state_index], state_index + 1 # Initialize the discussion initial_state, discussion_states = simulate_discussion() with gr.Blocks() as demo: gr.Markdown("# šŸŽ­ Consilium Roundtable Demo") gr.Markdown("**Watch the AI discussion unfold!** Click 'Next State' to see different phases of the discussion. šŸ“¼ Demo Video: https://youtu.be/oyYlf1BfuU8") # State management state_counter = gr.State(0) # The roundtable component roundtable = consilium_roundtable( label="AI Discussion Roundtable", show_label=True, label_icon="https://huggingface.co/front/assets/huggingface_logo-noborder.svg", value=initial_state ) with gr.Row(): next_btn = gr.Button("ā–¶ļø Next Discussion State", variant="primary") reset_btn = gr.Button("šŸ”„ Reset Discussion", variant="secondary") # Status display with gr.Row(): status_display = gr.Markdown("**Status:** Discussion ready to begin") def next_state(current_counter): new_state, new_counter = update_discussion_state(current_counter, discussion_states) # Convert to proper JSON string json_state = json.dumps(new_state) # Create status message thinking_list = new_state.get("thinking", []) current_speaker = new_state.get("currentSpeaker") if thinking_list: status = f"**Status:** {', '.join(thinking_list)} {'is' if len(thinking_list) == 1 else 'are'} thinking..." elif current_speaker: status = f"**Status:** {current_speaker} is responding..." else: status = "**Status:** Discussion in progress..." return json_state, new_counter, status def reset_discussion(): json_state = json.dumps(initial_state) return json_state, 0, "**Status:** Discussion reset - ready to begin" next_btn.click( next_state, inputs=[state_counter], outputs=[roundtable, state_counter, status_display] ) reset_btn.click( reset_discussion, outputs=[roundtable, state_counter, status_display] ) if __name__ == "__main__": demo.launch() ``` ## `consilium_roundtable` ### Initialization
name type default description
value ```python str | Callable | None ``` None JSON string containing the discussion state with participants, messages, current speaker, thinking states, and avatar images. If a function is provided, it will be called each time the app loads to set the initial value.
placeholder ```python str | None ``` None Not used in this component (roundtable displays participants instead).
label ```python str | I18nData | None ``` None The label for this component, displayed above the roundtable.
label_icon ```python str | None ``` "šŸŽ­" Icon displayed next to the label. Can be an emoji (default: "šŸŽ­") or a URL to an image. Set to None to disable.
every ```python Timer | float | None ``` None Continuously calls `value` to recalculate it if `value` is a function (useful for live discussion updates).
inputs ```python Component | Sequence[Component] | set[Component] | None ``` None Components that are used as inputs to calculate `value` if `value` is a function.
show_label ```python bool | None ``` None If True, will display the label above the roundtable.
scale ```python int | None ``` None Relative size compared to adjacent components in a Row or Blocks layout.
min_width ```python int ``` 600 Minimum pixel width for the component (default 600px for proper roundtable display).
visible ```python bool ``` True If False, component will be hidden.
rtl ```python bool ``` False Not used in this component.
elem_id ```python str | None ``` None An optional string assigned as the id of this component in the HTML DOM.
elem_classes ```python list[str] | str | None ``` None Optional list of CSS classes assigned to this component.
render ```python bool ``` True If False, component will not be rendered in the Blocks context initially.
key ```python int | str | tuple[int | str, ...] | None ``` None For gr.render() - components with the same key are treated as the same component across re-renders.
preserved_by_key ```python list[str] | str | None ``` "value" Parameters preserved across re-renders when using keys.
### Events | name | description | |:-----|:------------| | `change` | Triggered when the value of the consilium_roundtable changes either because of user input (e.g. a user types in a textbox) OR because of a function update (e.g. an image receives a value from the output of an event trigger). See `.input()` for a listener that is only triggered by user input. | | `input` | This listener is triggered when the user changes the value of the consilium_roundtable. | | `submit` | This listener is triggered when the user presses the Enter key while the consilium_roundtable is focused. | ### User function The impact on the users predict function varies depending on whether the component is used as an input or output for an event (or both). - When used as an Input, the component only impacts the input signature of the user function. - When used as an output, the component only impacts the return signature of the user function. The code snippet below is accurate in cases where the component is used as both an input and an output. - **As output:** Is passed, passes the JSON string value for processing. - **As input:** Should return, discussion state as dict or JSON string containing:. ```python def predict( value: str | None ) -> Any: return value ```