This is page 25 of 114. Use http://codebase.md/microsoft/semanticworkbench?lines=false&page={x} to view the full context.
# Directory Structure
```
├── .devcontainer
│ ├── .vscode
│ │ └── settings.json
│ ├── devcontainer.json
│ ├── OPTIMIZING_FOR_CODESPACES.md
│ ├── POST_SETUP_README.md
│ └── README.md
├── .dockerignore
├── .gitattributes
├── .github
│ ├── policheck.yml
│ └── workflows
│ ├── assistants-codespace-assistant.yml
│ ├── assistants-document-assistant.yml
│ ├── assistants-explorer-assistant.yml
│ ├── assistants-guided-conversation-assistant.yml
│ ├── assistants-knowledge-transfer-assistant.yml
│ ├── assistants-navigator-assistant.yml
│ ├── assistants-project-assistant.yml
│ ├── assistants-prospector-assistant.yml
│ ├── assistants-skill-assistant.yml
│ ├── libraries.yml
│ ├── mcp-server-giphy.yml
│ ├── mcp-server-memory-filesystem-edit.yml
│ ├── mcp-server-memory-user-bio.yml
│ ├── mcp-server-memory-whiteboard.yml
│ ├── mcp-server-open-deep-research-clone.yml
│ ├── mcp-server-web-research.yml
│ ├── workbench-app.yml
│ └── workbench-service.yml
├── .gitignore
├── .multi-root-tools
│ ├── Makefile
│ └── README.md
├── .vscode
│ ├── extensions.json
│ ├── launch.json
│ └── settings.json
├── ai_context
│ └── generated
│ ├── ASPIRE_ORCHESTRATOR.md
│ ├── ASSISTANT_CODESPACE.md
│ ├── ASSISTANT_DOCUMENT.md
│ ├── ASSISTANT_NAVIGATOR.md
│ ├── ASSISTANT_PROJECT.md
│ ├── ASSISTANT_PROSPECTOR.md
│ ├── ASSISTANTS_OTHER.md
│ ├── ASSISTANTS_OVERVIEW.md
│ ├── CONFIGURATION.md
│ ├── DOTNET_LIBRARIES.md
│ ├── EXAMPLES.md
│ ├── MCP_SERVERS.md
│ ├── PYTHON_LIBRARIES_AI_CLIENTS.md
│ ├── PYTHON_LIBRARIES_CORE.md
│ ├── PYTHON_LIBRARIES_EXTENSIONS.md
│ ├── PYTHON_LIBRARIES_SKILLS.md
│ ├── PYTHON_LIBRARIES_SPECIALIZED.md
│ ├── TOOLS.md
│ ├── WORKBENCH_FRONTEND.md
│ └── WORKBENCH_SERVICE.md
├── aspire-orchestrator
│ ├── .editorconfig
│ ├── Aspire.AppHost
│ │ ├── .gitignore
│ │ ├── appsettings.json
│ │ ├── Aspire.AppHost.csproj
│ │ ├── Program.cs
│ │ └── Properties
│ │ └── launchSettings.json
│ ├── Aspire.Extensions
│ │ ├── Aspire.Extensions.csproj
│ │ ├── Dashboard.cs
│ │ ├── DockerFileExtensions.cs
│ │ ├── PathNormalizer.cs
│ │ ├── UvAppHostingExtensions.cs
│ │ ├── UvAppResource.cs
│ │ ├── VirtualEnvironment.cs
│ │ └── WorkbenchServiceHostingExtensions.cs
│ ├── Aspire.ServiceDefaults
│ │ ├── Aspire.ServiceDefaults.csproj
│ │ └── Extensions.cs
│ ├── README.md
│ ├── run.sh
│ ├── SemanticWorkbench.Aspire.sln
│ └── SemanticWorkbench.Aspire.sln.DotSettings
├── assistants
│ ├── codespace-assistant
│ │ ├── .claude
│ │ │ └── settings.local.json
│ │ ├── .env.example
│ │ ├── .vscode
│ │ │ ├── extensions.json
│ │ │ ├── launch.json
│ │ │ └── settings.json
│ │ ├── assistant
│ │ │ ├── __init__.py
│ │ │ ├── assets
│ │ │ │ ├── icon_context_transfer.svg
│ │ │ │ └── icon.svg
│ │ │ ├── chat.py
│ │ │ ├── config.py
│ │ │ ├── helpers.py
│ │ │ ├── response
│ │ │ │ ├── __init__.py
│ │ │ │ ├── completion_handler.py
│ │ │ │ ├── models.py
│ │ │ │ ├── request_builder.py
│ │ │ │ ├── response.py
│ │ │ │ ├── step_handler.py
│ │ │ │ └── utils
│ │ │ │ ├── __init__.py
│ │ │ │ ├── abbreviations.py
│ │ │ │ ├── formatting_utils.py
│ │ │ │ ├── message_utils.py
│ │ │ │ └── openai_utils.py
│ │ │ ├── text_includes
│ │ │ │ ├── card_content_context_transfer.md
│ │ │ │ ├── card_content.md
│ │ │ │ ├── codespace_assistant_info.md
│ │ │ │ ├── context_transfer_assistant_info.md
│ │ │ │ ├── guardrails_prompt.txt
│ │ │ │ ├── guidance_prompt_context_transfer.txt
│ │ │ │ ├── guidance_prompt.txt
│ │ │ │ ├── instruction_prompt_context_transfer.txt
│ │ │ │ └── instruction_prompt.txt
│ │ │ └── whiteboard
│ │ │ ├── __init__.py
│ │ │ ├── _inspector.py
│ │ │ └── _whiteboard.py
│ │ ├── assistant.code-workspace
│ │ ├── Makefile
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ └── uv.lock
│ ├── document-assistant
│ │ ├── .env.example
│ │ ├── .vscode
│ │ │ ├── launch.json
│ │ │ └── settings.json
│ │ ├── assistant
│ │ │ ├── __init__.py
│ │ │ ├── assets
│ │ │ │ └── icon.svg
│ │ │ ├── chat.py
│ │ │ ├── config.py
│ │ │ ├── context_management
│ │ │ │ ├── __init__.py
│ │ │ │ └── inspector.py
│ │ │ ├── filesystem
│ │ │ │ ├── __init__.py
│ │ │ │ ├── _convert.py
│ │ │ │ ├── _file_sources.py
│ │ │ │ ├── _filesystem.py
│ │ │ │ ├── _inspector.py
│ │ │ │ ├── _model.py
│ │ │ │ ├── _prompts.py
│ │ │ │ └── _tasks.py
│ │ │ ├── guidance
│ │ │ │ ├── __init__.py
│ │ │ │ ├── dynamic_ui_inspector.py
│ │ │ │ ├── guidance_config.py
│ │ │ │ ├── guidance_prompts.py
│ │ │ │ └── README.md
│ │ │ ├── response
│ │ │ │ ├── __init__.py
│ │ │ │ ├── completion_handler.py
│ │ │ │ ├── models.py
│ │ │ │ ├── prompts.py
│ │ │ │ ├── responder.py
│ │ │ │ └── utils
│ │ │ │ ├── __init__.py
│ │ │ │ ├── formatting_utils.py
│ │ │ │ ├── message_utils.py
│ │ │ │ ├── openai_utils.py
│ │ │ │ ├── tokens_tiktoken.py
│ │ │ │ └── workbench_messages.py
│ │ │ ├── text_includes
│ │ │ │ └── document_assistant_info.md
│ │ │ ├── types.py
│ │ │ └── whiteboard
│ │ │ ├── __init__.py
│ │ │ ├── _inspector.py
│ │ │ └── _whiteboard.py
│ │ ├── assistant.code-workspace
│ │ ├── CLAUDE.md
│ │ ├── Makefile
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── test_convert.py
│ │ │ └── test_data
│ │ │ ├── blank_image.png
│ │ │ ├── Formatting Test.docx
│ │ │ ├── sample_data.csv
│ │ │ ├── sample_data.xlsx
│ │ │ ├── sample_page.html
│ │ │ ├── sample_presentation.pptx
│ │ │ └── simple_pdf.pdf
│ │ └── uv.lock
│ ├── explorer-assistant
│ │ ├── .env.example
│ │ ├── .vscode
│ │ │ ├── launch.json
│ │ │ └── settings.json
│ │ ├── assistant
│ │ │ ├── __init__.py
│ │ │ ├── chat.py
│ │ │ ├── config.py
│ │ │ ├── helpers.py
│ │ │ ├── response
│ │ │ │ ├── __init__.py
│ │ │ │ ├── model.py
│ │ │ │ ├── response_anthropic.py
│ │ │ │ ├── response_openai.py
│ │ │ │ └── response.py
│ │ │ └── text_includes
│ │ │ └── guardrails_prompt.txt
│ │ ├── assistant.code-workspace
│ │ ├── Makefile
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ └── uv.lock
│ ├── guided-conversation-assistant
│ │ ├── .env.example
│ │ ├── .vscode
│ │ │ ├── launch.json
│ │ │ └── settings.json
│ │ ├── assistant
│ │ │ ├── __init__.py
│ │ │ ├── agents
│ │ │ │ ├── guided_conversation
│ │ │ │ │ ├── config.py
│ │ │ │ │ ├── definition.py
│ │ │ │ │ └── definitions
│ │ │ │ │ ├── er_triage.py
│ │ │ │ │ ├── interview.py
│ │ │ │ │ ├── patient_intake.py
│ │ │ │ │ └── poem_feedback.py
│ │ │ │ └── guided_conversation_agent.py
│ │ │ ├── chat.py
│ │ │ ├── config.py
│ │ │ └── text_includes
│ │ │ └── guardrails_prompt.txt
│ │ ├── assistant.code-workspace
│ │ ├── Makefile
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ └── uv.lock
│ ├── knowledge-transfer-assistant
│ │ ├── .claude
│ │ │ └── settings.local.json
│ │ ├── .env.example
│ │ ├── .vscode
│ │ │ ├── launch.json
│ │ │ └── settings.json
│ │ ├── assistant
│ │ │ ├── __init__.py
│ │ │ ├── agentic
│ │ │ │ ├── __init__.py
│ │ │ │ ├── analysis.py
│ │ │ │ ├── coordinator_support.py
│ │ │ │ └── team_welcome.py
│ │ │ ├── assets
│ │ │ │ ├── icon-knowledge-transfer.svg
│ │ │ │ └── icon.svg
│ │ │ ├── assistant.py
│ │ │ ├── common.py
│ │ │ ├── config.py
│ │ │ ├── conversation_clients.py
│ │ │ ├── conversation_share_link.py
│ │ │ ├── data.py
│ │ │ ├── domain
│ │ │ │ ├── __init__.py
│ │ │ │ ├── audience_manager.py
│ │ │ │ ├── information_request_manager.py
│ │ │ │ ├── knowledge_brief_manager.py
│ │ │ │ ├── knowledge_digest_manager.py
│ │ │ │ ├── learning_objectives_manager.py
│ │ │ │ └── share_manager.py
│ │ │ ├── files.py
│ │ │ ├── logging.py
│ │ │ ├── notifications.py
│ │ │ ├── respond.py
│ │ │ ├── storage_models.py
│ │ │ ├── storage.py
│ │ │ ├── string_utils.py
│ │ │ ├── text_includes
│ │ │ │ ├── assistant_info.md
│ │ │ │ ├── card_content.md
│ │ │ │ ├── coordinator_instructions.txt
│ │ │ │ ├── coordinator_role.txt
│ │ │ │ ├── knowledge_digest_instructions.txt
│ │ │ │ ├── knowledge_digest_prompt.txt
│ │ │ │ ├── share_information_request_detection.txt
│ │ │ │ ├── team_instructions.txt
│ │ │ │ ├── team_role.txt
│ │ │ │ └── welcome_message_generation.txt
│ │ │ ├── tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── base.py
│ │ │ │ ├── information_requests.py
│ │ │ │ ├── learning_objectives.py
│ │ │ │ ├── learning_outcomes.py
│ │ │ │ ├── progress_tracking.py
│ │ │ │ └── share_setup.py
│ │ │ ├── ui_tabs
│ │ │ │ ├── __init__.py
│ │ │ │ ├── brief.py
│ │ │ │ ├── common.py
│ │ │ │ ├── debug.py
│ │ │ │ ├── learning.py
│ │ │ │ └── sharing.py
│ │ │ └── utils.py
│ │ ├── CLAUDE.md
│ │ ├── docs
│ │ │ ├── design
│ │ │ │ ├── actions.md
│ │ │ │ └── inference.md
│ │ │ ├── DEV_GUIDE.md
│ │ │ ├── how-kta-works.md
│ │ │ ├── JTBD.md
│ │ │ ├── knowledge-transfer-goals.md
│ │ │ ├── learning_assistance.md
│ │ │ ├── notable_claude_conversations
│ │ │ │ ├── clarifying_quad_modal_design.md
│ │ │ │ ├── CLAUDE_PROMPTS.md
│ │ │ │ ├── transfer_state.md
│ │ │ │ └── trying_the_context_agent.md
│ │ │ └── opportunities-of-knowledge-transfer.md
│ │ ├── knowledge-transfer-assistant.code-workspace
│ │ ├── Makefile
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── test_artifact_loading.py
│ │ │ ├── test_inspector.py
│ │ │ ├── test_share_manager.py
│ │ │ ├── test_share_storage.py
│ │ │ ├── test_share_tools.py
│ │ │ └── test_team_mode.py
│ │ └── uv.lock
│ ├── Makefile
│ ├── navigator-assistant
│ │ ├── .env.example
│ │ ├── .vscode
│ │ │ ├── launch.json
│ │ │ └── settings.json
│ │ ├── assistant
│ │ │ ├── __init__.py
│ │ │ ├── assets
│ │ │ │ ├── card_content.md
│ │ │ │ └── icon.svg
│ │ │ ├── chat.py
│ │ │ ├── config.py
│ │ │ ├── helpers.py
│ │ │ ├── response
│ │ │ │ ├── __init__.py
│ │ │ │ ├── completion_handler.py
│ │ │ │ ├── completion_requestor.py
│ │ │ │ ├── local_tool
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── add_assistant_to_conversation.py
│ │ │ │ │ ├── list_assistant_services.py
│ │ │ │ │ └── model.py
│ │ │ │ ├── models.py
│ │ │ │ ├── prompt.py
│ │ │ │ ├── request_builder.py
│ │ │ │ ├── response.py
│ │ │ │ ├── step_handler.py
│ │ │ │ └── utils
│ │ │ │ ├── __init__.py
│ │ │ │ ├── formatting_utils.py
│ │ │ │ ├── message_utils.py
│ │ │ │ ├── openai_utils.py
│ │ │ │ └── tools.py
│ │ │ ├── text_includes
│ │ │ │ ├── guardrails_prompt.md
│ │ │ │ ├── guidance_prompt.md
│ │ │ │ ├── instruction_prompt.md
│ │ │ │ ├── navigator_assistant_info.md
│ │ │ │ └── semantic_workbench_features.md
│ │ │ └── whiteboard
│ │ │ ├── __init__.py
│ │ │ ├── _inspector.py
│ │ │ └── _whiteboard.py
│ │ ├── Makefile
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ └── uv.lock
│ ├── project-assistant
│ │ ├── .cspell
│ │ │ └── custom-dictionary-workspace.txt
│ │ ├── .env.example
│ │ ├── .vscode
│ │ │ ├── launch.json
│ │ │ └── settings.json
│ │ ├── assistant
│ │ │ ├── __init__.py
│ │ │ ├── agentic
│ │ │ │ ├── __init__.py
│ │ │ │ ├── act.py
│ │ │ │ ├── coordinator_next_action.py
│ │ │ │ ├── create_invitation.py
│ │ │ │ ├── detect_audience_and_takeaways.py
│ │ │ │ ├── detect_coordinator_actions.py
│ │ │ │ ├── detect_information_request_needs.py
│ │ │ │ ├── detect_knowledge_package_gaps.py
│ │ │ │ ├── focus.py
│ │ │ │ ├── respond.py
│ │ │ │ ├── team_welcome.py
│ │ │ │ └── update_digest.py
│ │ │ ├── assets
│ │ │ │ ├── icon-knowledge-transfer.svg
│ │ │ │ └── icon.svg
│ │ │ ├── assistant.py
│ │ │ ├── common.py
│ │ │ ├── config.py
│ │ │ ├── conversation_clients.py
│ │ │ ├── data.py
│ │ │ ├── domain
│ │ │ │ ├── __init__.py
│ │ │ │ ├── audience_manager.py
│ │ │ │ ├── conversation_preferences_manager.py
│ │ │ │ ├── information_request_manager.py
│ │ │ │ ├── knowledge_brief_manager.py
│ │ │ │ ├── knowledge_digest_manager.py
│ │ │ │ ├── learning_objectives_manager.py
│ │ │ │ ├── share_manager.py
│ │ │ │ ├── tasks_manager.py
│ │ │ │ └── transfer_manager.py
│ │ │ ├── errors.py
│ │ │ ├── files.py
│ │ │ ├── logging.py
│ │ │ ├── notifications.py
│ │ │ ├── prompt_utils.py
│ │ │ ├── storage.py
│ │ │ ├── string_utils.py
│ │ │ ├── text_includes
│ │ │ │ ├── actor_instructions.md
│ │ │ │ ├── assistant_info.md
│ │ │ │ ├── card_content.md
│ │ │ │ ├── coordinator_instructions copy.md
│ │ │ │ ├── coordinator_instructions.md
│ │ │ │ ├── create_invitation.md
│ │ │ │ ├── detect_audience.md
│ │ │ │ ├── detect_coordinator_actions.md
│ │ │ │ ├── detect_information_request_needs.md
│ │ │ │ ├── detect_knowledge_package_gaps.md
│ │ │ │ ├── focus.md
│ │ │ │ ├── knowledge_digest_instructions.txt
│ │ │ │ ├── team_instructions.txt
│ │ │ │ ├── to_do.md
│ │ │ │ ├── update_knowledge_brief.md
│ │ │ │ ├── update_knowledge_digest.md
│ │ │ │ └── welcome_message_generation.txt
│ │ │ ├── tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── base.py
│ │ │ │ ├── conversation_preferences.py
│ │ │ │ ├── information_requests.py
│ │ │ │ ├── learning_objectives.py
│ │ │ │ ├── learning_outcomes.py
│ │ │ │ ├── progress_tracking.py
│ │ │ │ ├── share_setup.py
│ │ │ │ ├── system_reminders.py
│ │ │ │ ├── tasks.py
│ │ │ │ └── todo.py
│ │ │ ├── ui_tabs
│ │ │ │ ├── __init__.py
│ │ │ │ ├── brief.py
│ │ │ │ ├── common.py
│ │ │ │ ├── debug.py
│ │ │ │ ├── learning.py
│ │ │ │ └── sharing.py
│ │ │ └── utils.py
│ │ ├── CLAUDE.md
│ │ ├── docs
│ │ │ ├── design
│ │ │ │ ├── actions.md
│ │ │ │ ├── control_options.md
│ │ │ │ ├── design.md
│ │ │ │ ├── inference.md
│ │ │ │ └── PXL_20250814_190140267.jpg
│ │ │ ├── DEV_GUIDE.md
│ │ │ ├── how-kta-works.md
│ │ │ ├── JTBD.md
│ │ │ ├── knowledge-transfer-goals.md
│ │ │ ├── learning_assistance.md
│ │ │ ├── notable_claude_conversations
│ │ │ │ ├── clarifying_quad_modal_design.md
│ │ │ │ ├── CLAUDE_PROMPTS.md
│ │ │ │ ├── transfer_state.md
│ │ │ │ └── trying_the_context_agent.md
│ │ │ └── opportunities-of-knowledge-transfer.md
│ │ ├── knowledge-transfer-assistant.code-workspace
│ │ ├── Makefile
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── __init__.py
│ │ │ ├── test_artifact_loading.py
│ │ │ ├── test_inspector.py
│ │ │ ├── test_share_manager.py
│ │ │ ├── test_share_storage.py
│ │ │ └── test_team_mode.py
│ │ └── uv.lock
│ ├── prospector-assistant
│ │ ├── .env.example
│ │ ├── .vscode
│ │ │ ├── launch.json
│ │ │ └── settings.json
│ │ ├── assistant
│ │ │ ├── __init__.py
│ │ │ ├── agents
│ │ │ │ ├── artifact_agent.py
│ │ │ │ ├── document
│ │ │ │ │ ├── config.py
│ │ │ │ │ ├── gc_draft_content_feedback_config.py
│ │ │ │ │ ├── gc_draft_outline_feedback_config.py
│ │ │ │ │ ├── guided_conversation.py
│ │ │ │ │ └── state.py
│ │ │ │ └── document_agent.py
│ │ │ ├── artifact_creation_extension
│ │ │ │ ├── __init__.py
│ │ │ │ ├── _llm.py
│ │ │ │ ├── config.py
│ │ │ │ ├── document.py
│ │ │ │ ├── extension.py
│ │ │ │ ├── store.py
│ │ │ │ ├── test
│ │ │ │ │ ├── conftest.py
│ │ │ │ │ ├── evaluation.py
│ │ │ │ │ ├── test_completion_with_tools.py
│ │ │ │ │ └── test_extension.py
│ │ │ │ └── tools.py
│ │ │ ├── chat.py
│ │ │ ├── config.py
│ │ │ ├── form_fill_extension
│ │ │ │ ├── __init__.py
│ │ │ │ ├── config.py
│ │ │ │ ├── extension.py
│ │ │ │ ├── inspector.py
│ │ │ │ ├── state.py
│ │ │ │ └── steps
│ │ │ │ ├── __init__.py
│ │ │ │ ├── _guided_conversation.py
│ │ │ │ ├── _llm.py
│ │ │ │ ├── acquire_form_step.py
│ │ │ │ ├── extract_form_fields_step.py
│ │ │ │ ├── fill_form_step.py
│ │ │ │ └── types.py
│ │ │ ├── helpers.py
│ │ │ ├── legacy.py
│ │ │ └── text_includes
│ │ │ ├── artifact_agent_enabled.md
│ │ │ ├── guardrails_prompt.txt
│ │ │ ├── guided_conversation_agent_enabled.md
│ │ │ └── skills_agent_enabled.md
│ │ ├── assistant.code-workspace
│ │ ├── gc_learnings
│ │ │ ├── gc_learnings.md
│ │ │ └── images
│ │ │ ├── gc_conversation_plan_fcn.png
│ │ │ ├── gc_conversation_plan_template.png
│ │ │ ├── gc_execute_plan_callstack.png
│ │ │ ├── gc_functions.png
│ │ │ ├── gc_generate_plan_callstack.png
│ │ │ ├── gc_get_resource_instructions.png
│ │ │ ├── gc_get_termination_instructions.png
│ │ │ ├── gc_kernel_arguments.png
│ │ │ ├── gc_plan_calls.png
│ │ │ ├── gc_termination_instructions.png
│ │ │ ├── sk_get_chat_message_contents.png
│ │ │ ├── sk_inner_get_chat_message_contents.png
│ │ │ ├── sk_send_request_prep.png
│ │ │ └── sk_send_request.png
│ │ ├── Makefile
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ └── uv.lock
│ └── skill-assistant
│ ├── .env.example
│ ├── .vscode
│ │ ├── launch.json
│ │ └── settings.json
│ ├── assistant
│ │ ├── __init__.py
│ │ ├── config.py
│ │ ├── logging.py
│ │ ├── skill_assistant.py
│ │ ├── skill_engine_registry.py
│ │ ├── skill_event_mapper.py
│ │ ├── text_includes
│ │ │ └── guardrails_prompt.txt
│ │ └── workbench_helpers.py
│ ├── assistant.code-workspace
│ ├── Makefile
│ ├── pyproject.toml
│ ├── README.md
│ ├── tests
│ │ └── test_setup.py
│ └── uv.lock
├── CLAUDE.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── docs
│ ├── .vscode
│ │ └── settings.json
│ ├── ASSISTANT_CONFIG.md
│ ├── ASSISTANT_DEVELOPMENT_GUIDE.md
│ ├── CUSTOM_APP_REGISTRATION.md
│ ├── HOSTED_ASSISTANT_WITH_LOCAL_MCP_SERVERS.md
│ ├── images
│ │ ├── architecture-animation.gif
│ │ ├── configure_assistant.png
│ │ ├── conversation_canvas_open.png
│ │ ├── conversation_duplicate.png
│ │ ├── conversation_export.png
│ │ ├── conversation_share_dialog.png
│ │ ├── conversation_share_link.png
│ │ ├── dashboard_configured_view.png
│ │ ├── dashboard_view.png
│ │ ├── license_agreement.png
│ │ ├── message_bar.png
│ │ ├── message_inspection.png
│ │ ├── message_link.png
│ │ ├── new_prospector_assistant_dialog.png
│ │ ├── open_conversation_canvas.png
│ │ ├── prospector_example.png
│ │ ├── readme1.png
│ │ ├── readme2.png
│ │ ├── readme3.png
│ │ ├── rewind.png
│ │ ├── signin_page.png
│ │ └── splash_screen.png
│ ├── LOCAL_ASSISTANT_WITH_REMOTE_WORKBENCH.md
│ ├── SETUP_DEV_ENVIRONMENT.md
│ └── WORKBENCH_APP.md
├── examples
│ ├── dotnet
│ │ ├── .editorconfig
│ │ ├── dotnet-01-echo-bot
│ │ │ ├── appsettings.json
│ │ │ ├── dotnet-01-echo-bot.csproj
│ │ │ ├── MyAgent.cs
│ │ │ ├── MyAgentConfig.cs
│ │ │ ├── MyWorkbenchConnector.cs
│ │ │ ├── Program.cs
│ │ │ └── README.md
│ │ ├── dotnet-02-message-types-demo
│ │ │ ├── appsettings.json
│ │ │ ├── ConnectorExtensions.cs
│ │ │ ├── docs
│ │ │ │ ├── abc.png
│ │ │ │ ├── code.png
│ │ │ │ ├── config.png
│ │ │ │ ├── echo.png
│ │ │ │ ├── markdown.png
│ │ │ │ ├── mermaid.png
│ │ │ │ ├── reverse.png
│ │ │ │ └── safety-check.png
│ │ │ ├── dotnet-02-message-types-demo.csproj
│ │ │ ├── MyAgent.cs
│ │ │ ├── MyAgentConfig.cs
│ │ │ ├── MyWorkbenchConnector.cs
│ │ │ ├── Program.cs
│ │ │ └── README.md
│ │ └── dotnet-03-simple-chatbot
│ │ ├── appsettings.json
│ │ ├── ConnectorExtensions.cs
│ │ ├── dotnet-03-simple-chatbot.csproj
│ │ ├── MyAgent.cs
│ │ ├── MyAgentConfig.cs
│ │ ├── MyWorkbenchConnector.cs
│ │ ├── Program.cs
│ │ └── README.md
│ ├── Makefile
│ └── python
│ ├── python-01-echo-bot
│ │ ├── .env.example
│ │ ├── .vscode
│ │ │ ├── launch.json
│ │ │ └── settings.json
│ │ ├── assistant
│ │ │ ├── __init__.py
│ │ │ ├── chat.py
│ │ │ └── config.py
│ │ ├── assistant.code-workspace
│ │ ├── Makefile
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ └── uv.lock
│ ├── python-02-simple-chatbot
│ │ ├── .env.example
│ │ ├── .vscode
│ │ │ ├── launch.json
│ │ │ └── settings.json
│ │ ├── assistant
│ │ │ ├── __init__.py
│ │ │ ├── chat.py
│ │ │ ├── config.py
│ │ │ └── text_includes
│ │ │ └── guardrails_prompt.txt
│ │ ├── assistant.code-workspace
│ │ ├── Makefile
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ └── uv.lock
│ └── python-03-multimodel-chatbot
│ ├── .env.example
│ ├── .vscode
│ │ ├── launch.json
│ │ └── settings.json
│ ├── assistant
│ │ ├── __init__.py
│ │ ├── chat.py
│ │ ├── config.py
│ │ ├── model_adapters.py
│ │ └── text_includes
│ │ └── guardrails_prompt.txt
│ ├── assistant.code-workspace
│ ├── Makefile
│ ├── pyproject.toml
│ ├── README.md
│ └── uv.lock
├── KNOWN_ISSUES.md
├── libraries
│ ├── dotnet
│ │ ├── .editorconfig
│ │ ├── pack.sh
│ │ ├── README.md
│ │ ├── SemanticWorkbench.sln
│ │ ├── SemanticWorkbench.sln.DotSettings
│ │ └── WorkbenchConnector
│ │ ├── AgentBase.cs
│ │ ├── AgentConfig
│ │ │ ├── AgentConfigBase.cs
│ │ │ ├── AgentConfigPropertyAttribute.cs
│ │ │ └── ConfigUtils.cs
│ │ ├── Constants.cs
│ │ ├── IAgentBase.cs
│ │ ├── icon.png
│ │ ├── Models
│ │ │ ├── Command.cs
│ │ │ ├── Conversation.cs
│ │ │ ├── ConversationEvent.cs
│ │ │ ├── DebugInfo.cs
│ │ │ ├── Insight.cs
│ │ │ ├── Message.cs
│ │ │ ├── MessageMetadata.cs
│ │ │ ├── Participant.cs
│ │ │ ├── Sender.cs
│ │ │ └── ServiceInfo.cs
│ │ ├── Storage
│ │ │ ├── AgentInfo.cs
│ │ │ ├── AgentServiceStorage.cs
│ │ │ └── IAgentServiceStorage.cs
│ │ ├── StringLoggingExtensions.cs
│ │ ├── Webservice.cs
│ │ ├── WorkbenchConfig.cs
│ │ ├── WorkbenchConnector.cs
│ │ └── WorkbenchConnector.csproj
│ ├── Makefile
│ └── python
│ ├── anthropic-client
│ │ ├── .vscode
│ │ │ └── settings.json
│ │ ├── anthropic_client
│ │ │ ├── __init__.py
│ │ │ ├── client.py
│ │ │ ├── config.py
│ │ │ └── messages.py
│ │ ├── Makefile
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ └── uv.lock
│ ├── assistant-data-gen
│ │ ├── .vscode
│ │ │ ├── launch.json
│ │ │ └── settings.json
│ │ ├── assistant_data_gen
│ │ │ ├── __init__.py
│ │ │ ├── assistant_api.py
│ │ │ ├── config.py
│ │ │ ├── gce
│ │ │ │ ├── __init__.py
│ │ │ │ ├── gce_agent.py
│ │ │ │ └── prompts.py
│ │ │ └── pydantic_ai_utils.py
│ │ ├── configs
│ │ │ └── document_assistant_example_config.yaml
│ │ ├── Makefile
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── scripts
│ │ │ ├── gce_simulation.py
│ │ │ └── generate_scenario.py
│ │ └── uv.lock
│ ├── assistant-drive
│ │ ├── .gitignore
│ │ ├── .vscode
│ │ │ ├── extensions.json
│ │ │ └── settings.json
│ │ ├── assistant_drive
│ │ │ ├── __init__.py
│ │ │ ├── drive.py
│ │ │ └── tests
│ │ │ └── test_basic.py
│ │ ├── Makefile
│ │ ├── pyproject.toml
│ │ ├── pytest.ini
│ │ ├── README.md
│ │ ├── usage.ipynb
│ │ └── uv.lock
│ ├── assistant-extensions
│ │ ├── .vscode
│ │ │ └── settings.json
│ │ ├── assistant_extensions
│ │ │ ├── __init__.py
│ │ │ ├── ai_clients
│ │ │ │ └── config.py
│ │ │ ├── artifacts
│ │ │ │ ├── __init__.py
│ │ │ │ ├── _artifacts.py
│ │ │ │ ├── _inspector.py
│ │ │ │ └── _model.py
│ │ │ ├── attachments
│ │ │ │ ├── __init__.py
│ │ │ │ ├── _attachments.py
│ │ │ │ ├── _convert.py
│ │ │ │ ├── _model.py
│ │ │ │ ├── _shared.py
│ │ │ │ └── _summarizer.py
│ │ │ ├── chat_context_toolkit
│ │ │ │ ├── __init__.py
│ │ │ │ ├── _config.py
│ │ │ │ ├── archive
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── _archive.py
│ │ │ │ │ └── _summarizer.py
│ │ │ │ ├── message_history
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── _history.py
│ │ │ │ │ └── _message.py
│ │ │ │ └── virtual_filesystem
│ │ │ │ ├── __init__.py
│ │ │ │ ├── _archive_file_source.py
│ │ │ │ └── _attachments_file_source.py
│ │ │ ├── dashboard_card
│ │ │ │ ├── __init__.py
│ │ │ │ └── _dashboard_card.py
│ │ │ ├── document_editor
│ │ │ │ ├── __init__.py
│ │ │ │ ├── _extension.py
│ │ │ │ ├── _inspector.py
│ │ │ │ └── _model.py
│ │ │ ├── mcp
│ │ │ │ ├── __init__.py
│ │ │ │ ├── _assistant_file_resource_handler.py
│ │ │ │ ├── _client_utils.py
│ │ │ │ ├── _devtunnel.py
│ │ │ │ ├── _model.py
│ │ │ │ ├── _openai_utils.py
│ │ │ │ ├── _sampling_handler.py
│ │ │ │ ├── _tool_utils.py
│ │ │ │ └── _workbench_file_resource_handler.py
│ │ │ ├── navigator
│ │ │ │ ├── __init__.py
│ │ │ │ └── _navigator.py
│ │ │ └── workflows
│ │ │ ├── __init__.py
│ │ │ ├── _model.py
│ │ │ ├── _workflows.py
│ │ │ └── runners
│ │ │ └── _user_proxy.py
│ │ ├── Makefile
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── test
│ │ │ └── attachments
│ │ │ └── test_attachments.py
│ │ └── uv.lock
│ ├── chat-context-toolkit
│ │ ├── .claude
│ │ │ └── settings.local.json
│ │ ├── .env.sample
│ │ ├── .vscode
│ │ │ └── settings.json
│ │ ├── assets
│ │ │ ├── archive_v1.png
│ │ │ ├── history_v1.png
│ │ │ └── vfs_v1.png
│ │ ├── chat_context_toolkit
│ │ │ ├── __init__.py
│ │ │ ├── archive
│ │ │ │ ├── __init__.py
│ │ │ │ ├── _archive_reader.py
│ │ │ │ ├── _archive_task_queue.py
│ │ │ │ ├── _state.py
│ │ │ │ ├── _types.py
│ │ │ │ └── summarization
│ │ │ │ ├── __init__.py
│ │ │ │ └── _summarizer.py
│ │ │ ├── history
│ │ │ │ ├── __init__.py
│ │ │ │ ├── _budget.py
│ │ │ │ ├── _decorators.py
│ │ │ │ ├── _history.py
│ │ │ │ ├── _prioritize.py
│ │ │ │ ├── _types.py
│ │ │ │ └── tool_abbreviations
│ │ │ │ ├── __init__.py
│ │ │ │ └── _tool_abbreviations.py
│ │ │ └── virtual_filesystem
│ │ │ ├── __init__.py
│ │ │ ├── _types.py
│ │ │ ├── _virtual_filesystem.py
│ │ │ ├── README.md
│ │ │ └── tools
│ │ │ ├── __init__.py
│ │ │ ├── _ls_tool.py
│ │ │ ├── _tools.py
│ │ │ └── _view_tool.py
│ │ ├── CLAUDE.md
│ │ ├── Makefile
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── test
│ │ │ ├── archive
│ │ │ │ └── test_archive_reader.py
│ │ │ ├── history
│ │ │ │ ├── test_abbreviate_messages.py
│ │ │ │ ├── test_history.py
│ │ │ │ ├── test_pair_and_order_tool_messages.py
│ │ │ │ ├── test_prioritize.py
│ │ │ │ └── test_truncate_messages.py
│ │ │ └── virtual_filesystem
│ │ │ ├── test_virtual_filesystem.py
│ │ │ └── tools
│ │ │ ├── test_ls_tool.py
│ │ │ ├── test_tools.py
│ │ │ └── test_view_tool.py
│ │ └── uv.lock
│ ├── content-safety
│ │ ├── .vscode
│ │ │ └── settings.json
│ │ ├── content_safety
│ │ │ ├── __init__.py
│ │ │ ├── evaluators
│ │ │ │ ├── __init__.py
│ │ │ │ ├── azure_content_safety
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── config.py
│ │ │ │ │ └── evaluator.py
│ │ │ │ ├── config.py
│ │ │ │ ├── evaluator.py
│ │ │ │ └── openai_moderations
│ │ │ │ ├── __init__.py
│ │ │ │ ├── config.py
│ │ │ │ └── evaluator.py
│ │ │ └── README.md
│ │ ├── Makefile
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ └── uv.lock
│ ├── events
│ │ ├── .vscode
│ │ │ └── settings.json
│ │ ├── events
│ │ │ ├── __init__.py
│ │ │ └── events.py
│ │ ├── Makefile
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ └── uv.lock
│ ├── guided-conversation
│ │ ├── .vscode
│ │ │ └── settings.json
│ │ ├── guided_conversation
│ │ │ ├── __init__.py
│ │ │ ├── functions
│ │ │ │ ├── __init__.py
│ │ │ │ ├── conversation_plan.py
│ │ │ │ ├── execution.py
│ │ │ │ └── final_update_plan.py
│ │ │ ├── guided_conversation_agent.py
│ │ │ ├── plugins
│ │ │ │ ├── __init__.py
│ │ │ │ ├── agenda.py
│ │ │ │ └── artifact.py
│ │ │ └── utils
│ │ │ ├── __init__.py
│ │ │ ├── base_model_llm.py
│ │ │ ├── conversation_helpers.py
│ │ │ ├── openai_tool_calling.py
│ │ │ ├── plugin_helpers.py
│ │ │ └── resources.py
│ │ ├── Makefile
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ └── uv.lock
│ ├── llm-client
│ │ ├── .vscode
│ │ │ └── settings.json
│ │ ├── llm_client
│ │ │ ├── __init__.py
│ │ │ └── model.py
│ │ ├── Makefile
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ └── uv.lock
│ ├── Makefile
│ ├── mcp-extensions
│ │ ├── .vscode
│ │ │ └── settings.json
│ │ ├── Makefile
│ │ ├── mcp_extensions
│ │ │ ├── __init__.py
│ │ │ ├── _client_session.py
│ │ │ ├── _model.py
│ │ │ ├── _sampling.py
│ │ │ ├── _server_extensions.py
│ │ │ ├── _tool_utils.py
│ │ │ ├── llm
│ │ │ │ ├── __init__.py
│ │ │ │ ├── chat_completion.py
│ │ │ │ ├── helpers.py
│ │ │ │ ├── llm_types.py
│ │ │ │ ├── mcp_chat_completion.py
│ │ │ │ └── openai_chat_completion.py
│ │ │ └── server
│ │ │ ├── __init__.py
│ │ │ └── storage.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ └── test_tool_utils.py
│ │ └── uv.lock
│ ├── mcp-tunnel
│ │ ├── .vscode
│ │ │ └── settings.json
│ │ ├── Makefile
│ │ ├── mcp_tunnel
│ │ │ ├── __init__.py
│ │ │ ├── _devtunnel.py
│ │ │ ├── _dir.py
│ │ │ └── _main.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ └── uv.lock
│ ├── openai-client
│ │ ├── .vscode
│ │ │ └── settings.json
│ │ ├── Makefile
│ │ ├── openai_client
│ │ │ ├── __init__.py
│ │ │ ├── chat_driver
│ │ │ │ ├── __init__.py
│ │ │ │ ├── chat_driver.ipynb
│ │ │ │ ├── chat_driver.py
│ │ │ │ ├── message_history_providers
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── in_memory_message_history_provider.py
│ │ │ │ │ ├── local_message_history_provider.py
│ │ │ │ │ ├── message_history_provider.py
│ │ │ │ │ └── tests
│ │ │ │ │ └── formatted_instructions_test.py
│ │ │ │ └── README.md
│ │ │ ├── client.py
│ │ │ ├── completion.py
│ │ │ ├── config.py
│ │ │ ├── errors.py
│ │ │ ├── logging.py
│ │ │ ├── messages.py
│ │ │ ├── tokens.py
│ │ │ └── tools.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── test_command_parsing.py
│ │ │ ├── test_formatted_messages.py
│ │ │ ├── test_messages.py
│ │ │ └── test_tokens.py
│ │ └── uv.lock
│ ├── semantic-workbench-api-model
│ │ ├── .vscode
│ │ │ └── settings.json
│ │ ├── Makefile
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── semantic_workbench_api_model
│ │ │ ├── __init__.py
│ │ │ ├── assistant_model.py
│ │ │ ├── assistant_service_client.py
│ │ │ ├── workbench_model.py
│ │ │ └── workbench_service_client.py
│ │ └── uv.lock
│ ├── semantic-workbench-assistant
│ │ ├── .vscode
│ │ │ ├── launch.json
│ │ │ └── settings.json
│ │ ├── Makefile
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── semantic_workbench_assistant
│ │ │ ├── __init__.py
│ │ │ ├── assistant_app
│ │ │ │ ├── __init__.py
│ │ │ │ ├── assistant.py
│ │ │ │ ├── config.py
│ │ │ │ ├── content_safety.py
│ │ │ │ ├── context.py
│ │ │ │ ├── error.py
│ │ │ │ ├── export_import.py
│ │ │ │ ├── protocol.py
│ │ │ │ └── service.py
│ │ │ ├── assistant_service.py
│ │ │ ├── auth.py
│ │ │ ├── canonical.py
│ │ │ ├── command.py
│ │ │ ├── config.py
│ │ │ ├── logging_config.py
│ │ │ ├── settings.py
│ │ │ ├── start.py
│ │ │ └── storage.py
│ │ ├── tests
│ │ │ ├── conftest.py
│ │ │ ├── test_assistant_app.py
│ │ │ ├── test_canonical.py
│ │ │ ├── test_config.py
│ │ │ └── test_storage.py
│ │ └── uv.lock
│ └── skills
│ ├── .vscode
│ │ └── settings.json
│ ├── Makefile
│ ├── README.md
│ └── skill-library
│ ├── .vscode
│ │ └── settings.json
│ ├── docs
│ │ └── vs-recipe-tool.md
│ ├── Makefile
│ ├── pyproject.toml
│ ├── README.md
│ ├── skill_library
│ │ ├── __init__.py
│ │ ├── chat_driver_helpers.py
│ │ ├── cli
│ │ │ ├── azure_openai.py
│ │ │ ├── conversation_history.py
│ │ │ ├── README.md
│ │ │ ├── run_routine.py
│ │ │ ├── settings.py
│ │ │ └── skill_logger.py
│ │ ├── engine.py
│ │ ├── llm_info.txt
│ │ ├── logging.py
│ │ ├── README.md
│ │ ├── routine_stack.py
│ │ ├── skill.py
│ │ ├── skills
│ │ │ ├── common
│ │ │ │ ├── __init__.py
│ │ │ │ ├── common_skill.py
│ │ │ │ └── routines
│ │ │ │ ├── bing_search.py
│ │ │ │ ├── consolidate.py
│ │ │ │ ├── echo.py
│ │ │ │ ├── gather_context.py
│ │ │ │ ├── get_content_from_url.py
│ │ │ │ ├── gpt_complete.py
│ │ │ │ ├── select_user_intent.py
│ │ │ │ └── summarize.py
│ │ │ ├── eval
│ │ │ │ ├── __init__.py
│ │ │ │ ├── eval_skill.py
│ │ │ │ └── routines
│ │ │ │ └── eval.py
│ │ │ ├── fabric
│ │ │ │ ├── __init__.py
│ │ │ │ ├── fabric_skill.py
│ │ │ │ ├── patterns
│ │ │ │ │ ├── agility_story
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── ai
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── analyze_answers
│ │ │ │ │ │ ├── README.md
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── analyze_candidates
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── analyze_cfp_submission
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── analyze_claims
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── analyze_comments
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── analyze_debate
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── analyze_email_headers
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── analyze_incident
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── analyze_interviewer_techniques
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── analyze_logs
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── analyze_malware
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── analyze_military_strategy
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── analyze_mistakes
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── analyze_paper
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── analyze_patent
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── analyze_personality
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── analyze_presentation
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── analyze_product_feedback
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── analyze_proposition
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── analyze_prose
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── analyze_prose_json
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── analyze_prose_pinker
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── analyze_risk
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── analyze_sales_call
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── analyze_spiritual_text
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── analyze_tech_impact
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── analyze_threat_report
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── analyze_threat_report_cmds
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── analyze_threat_report_trends
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── answer_interview_question
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── ask_secure_by_design_questions
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── ask_uncle_duke
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── capture_thinkers_work
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── check_agreement
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── clean_text
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── coding_master
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── compare_and_contrast
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── convert_to_markdown
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_5_sentence_summary
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_academic_paper
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_ai_jobs_analysis
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_aphorisms
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── create_art_prompt
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_better_frame
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── create_coding_project
│ │ │ │ │ │ ├── README.md
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_command
│ │ │ │ │ │ ├── README.md
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── create_cyber_summary
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_design_document
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_diy
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_formal_email
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_git_diff_commit
│ │ │ │ │ │ ├── README.md
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_graph_from_input
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_hormozi_offer
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_idea_compass
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_investigation_visualization
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_keynote
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_logo
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── create_markmap_visualization
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_mermaid_visualization
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_mermaid_visualization_for_github
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_micro_summary
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_network_threat_landscape
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── create_newsletter_entry
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── create_npc
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── create_pattern
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_prd
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_prediction_block
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_quiz
│ │ │ │ │ │ ├── README.md
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_reading_plan
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_recursive_outline
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_report_finding
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── create_rpg_summary
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_security_update
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── create_show_intro
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_sigma_rules
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_story_explanation
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_stride_threat_model
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_summary
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_tags
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_threat_scenarios
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_ttrc_graph
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_ttrc_narrative
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_upgrade_pack
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_user_story
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── create_video_chapters
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── create_visualization
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── dialog_with_socrates
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── enrich_blog_post
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── explain_code
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── explain_docs
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── explain_math
│ │ │ │ │ │ ├── README.md
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── explain_project
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── explain_terms
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── export_data_as_csv
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_algorithm_update_recommendations
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── extract_article_wisdom
│ │ │ │ │ │ ├── dmiessler
│ │ │ │ │ │ │ └── extract_wisdom-1.0.0
│ │ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ │ └── user.md
│ │ │ │ │ │ ├── README.md
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── extract_book_ideas
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_book_recommendations
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_business_ideas
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_controversial_ideas
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_core_message
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_ctf_writeup
│ │ │ │ │ │ ├── README.md
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_domains
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_extraordinary_claims
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_ideas
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_insights
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_insights_dm
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_instructions
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_jokes
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_latest_video
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_main_idea
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_most_redeeming_thing
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_patterns
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_poc
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── extract_predictions
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_primary_problem
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_primary_solution
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_product_features
│ │ │ │ │ │ ├── dmiessler
│ │ │ │ │ │ │ └── extract_wisdom-1.0.0
│ │ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ │ └── user.md
│ │ │ │ │ │ ├── README.md
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_questions
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_recipe
│ │ │ │ │ │ ├── README.md
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_recommendations
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── extract_references
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── extract_skills
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_song_meaning
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_sponsors
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_videoid
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── extract_wisdom
│ │ │ │ │ │ ├── dmiessler
│ │ │ │ │ │ │ └── extract_wisdom-1.0.0
│ │ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ │ └── user.md
│ │ │ │ │ │ ├── README.md
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_wisdom_agents
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_wisdom_dm
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── extract_wisdom_nometa
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── find_hidden_message
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── find_logical_fallacies
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── get_wow_per_minute
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── get_youtube_rss
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── humanize
│ │ │ │ │ │ ├── README.md
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── identify_dsrp_distinctions
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── identify_dsrp_perspectives
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── identify_dsrp_relationships
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── identify_dsrp_systems
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── identify_job_stories
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── improve_academic_writing
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── improve_prompt
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── improve_report_finding
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── improve_writing
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── judge_output
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── label_and_rate
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── loaded
│ │ │ │ │ ├── md_callout
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── official_pattern_template
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── pattern_explanations.md
│ │ │ │ │ ├── prepare_7s_strategy
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── provide_guidance
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── rate_ai_response
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── rate_ai_result
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── rate_content
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── rate_value
│ │ │ │ │ │ ├── README.md
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── raw_query
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── raycast
│ │ │ │ │ │ ├── capture_thinkers_work
│ │ │ │ │ │ ├── create_story_explanation
│ │ │ │ │ │ ├── extract_primary_problem
│ │ │ │ │ │ ├── extract_wisdom
│ │ │ │ │ │ └── yt
│ │ │ │ │ ├── recommend_artists
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── recommend_pipeline_upgrades
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── recommend_talkpanel_topics
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── refine_design_document
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── review_design
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── sanitize_broken_html_to_markdown
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── show_fabric_options_markmap
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── solve_with_cot
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── stringify
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── suggest_pattern
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── summarize
│ │ │ │ │ │ ├── dmiessler
│ │ │ │ │ │ │ └── summarize
│ │ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ │ └── user.md
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── summarize_debate
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── summarize_git_changes
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── summarize_git_diff
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── summarize_lecture
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── summarize_legislation
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── summarize_meeting
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── summarize_micro
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── summarize_newsletter
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── summarize_paper
│ │ │ │ │ │ ├── README.md
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── summarize_prompt
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── summarize_pull-requests
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── summarize_rpg_session
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── t_analyze_challenge_handling
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── t_check_metrics
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── t_create_h3_career
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── t_create_opening_sentences
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── t_describe_life_outlook
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── t_extract_intro_sentences
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── t_extract_panel_topics
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── t_find_blindspots
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── t_find_negative_thinking
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── t_find_neglected_goals
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── t_give_encouragement
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── t_red_team_thinking
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── t_threat_model_plans
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── t_visualize_mission_goals_projects
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── t_year_in_review
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── to_flashcards
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── transcribe_minutes
│ │ │ │ │ │ ├── README.md
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── translate
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── tweet
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── write_essay
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── write_hackerone_report
│ │ │ │ │ │ ├── README.md
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── write_latex
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── write_micro_essay
│ │ │ │ │ │ └── system.md
│ │ │ │ │ ├── write_nuclei_template_rule
│ │ │ │ │ │ ├── system.md
│ │ │ │ │ │ └── user.md
│ │ │ │ │ ├── write_pull-request
│ │ │ │ │ │ └── system.md
│ │ │ │ │ └── write_semgrep_rule
│ │ │ │ │ ├── system.md
│ │ │ │ │ └── user.md
│ │ │ │ └── routines
│ │ │ │ ├── list.py
│ │ │ │ ├── run.py
│ │ │ │ └── show.py
│ │ │ ├── guided_conversation
│ │ │ │ ├── __init__.py
│ │ │ │ ├── agenda.py
│ │ │ │ ├── artifact_helpers.py
│ │ │ │ ├── chat_completions
│ │ │ │ │ ├── fix_agenda_error.py
│ │ │ │ │ ├── fix_artifact_error.py
│ │ │ │ │ ├── generate_agenda.py
│ │ │ │ │ ├── generate_artifact_updates.py
│ │ │ │ │ ├── generate_final_artifact.py
│ │ │ │ │ └── generate_message.py
│ │ │ │ ├── conversation_guides
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── acrostic_poem.py
│ │ │ │ │ ├── er_triage.py
│ │ │ │ │ ├── interview.py
│ │ │ │ │ └── patient_intake.py
│ │ │ │ ├── guide.py
│ │ │ │ ├── guided_conversation_skill.py
│ │ │ │ ├── logging.py
│ │ │ │ ├── message.py
│ │ │ │ ├── resources.py
│ │ │ │ ├── routines
│ │ │ │ │ └── guided_conversation.py
│ │ │ │ └── tests
│ │ │ │ ├── conftest.py
│ │ │ │ ├── test_artifact_helpers.py
│ │ │ │ ├── test_generate_agenda.py
│ │ │ │ ├── test_generate_artifact_updates.py
│ │ │ │ ├── test_generate_final_artifact.py
│ │ │ │ └── test_resource.py
│ │ │ ├── meta
│ │ │ │ ├── __init__.py
│ │ │ │ ├── meta_skill.py
│ │ │ │ ├── README.md
│ │ │ │ └── routines
│ │ │ │ └── generate_routine.py
│ │ │ ├── posix
│ │ │ │ ├── __init__.py
│ │ │ │ ├── posix_skill.py
│ │ │ │ ├── routines
│ │ │ │ │ ├── append_file.py
│ │ │ │ │ ├── cd.py
│ │ │ │ │ ├── ls.py
│ │ │ │ │ ├── make_home_dir.py
│ │ │ │ │ ├── mkdir.py
│ │ │ │ │ ├── mv.py
│ │ │ │ │ ├── pwd.py
│ │ │ │ │ ├── read_file.py
│ │ │ │ │ ├── rm.py
│ │ │ │ │ ├── touch.py
│ │ │ │ │ └── write_file.py
│ │ │ │ └── sandbox_shell.py
│ │ │ ├── README.md
│ │ │ ├── research
│ │ │ │ ├── __init__.py
│ │ │ │ ├── README.md
│ │ │ │ ├── research_skill.py
│ │ │ │ └── routines
│ │ │ │ ├── answer_question_about_content.py
│ │ │ │ ├── evaluate_answer.py
│ │ │ │ ├── generate_research_plan.py
│ │ │ │ ├── generate_search_query.py
│ │ │ │ ├── update_research_plan.py
│ │ │ │ ├── web_research.py
│ │ │ │ └── web_search.py
│ │ │ ├── research2
│ │ │ │ ├── __init__.py
│ │ │ │ ├── README.md
│ │ │ │ ├── research_skill.py
│ │ │ │ └── routines
│ │ │ │ ├── facts.py
│ │ │ │ ├── make_final_report.py
│ │ │ │ ├── research.py
│ │ │ │ ├── search_plan.py
│ │ │ │ ├── search.py
│ │ │ │ └── visit_pages.py
│ │ │ └── web_research
│ │ │ ├── __init__.py
│ │ │ ├── README.md
│ │ │ ├── research_skill.py
│ │ │ └── routines
│ │ │ ├── facts.py
│ │ │ ├── make_final_report.py
│ │ │ ├── research.py
│ │ │ ├── search_plan.py
│ │ │ ├── search.py
│ │ │ └── visit_pages.py
│ │ ├── tests
│ │ │ ├── test_common_skill.py
│ │ │ ├── test_integration.py
│ │ │ ├── test_routine_stack.py
│ │ │ ├── tst_skill
│ │ │ │ ├── __init__.py
│ │ │ │ └── routines
│ │ │ │ ├── __init__.py
│ │ │ │ └── a_routine.py
│ │ │ └── utilities
│ │ │ ├── test_find_template_vars.py
│ │ │ ├── test_make_arg_set.py
│ │ │ ├── test_paramspec.py
│ │ │ ├── test_parse_command_string.py
│ │ │ └── test_to_string.py
│ │ ├── types.py
│ │ ├── usage.py
│ │ └── utilities.py
│ └── uv.lock
├── LICENSE
├── Makefile
├── mcp-servers
│ ├── ai-assist-content
│ │ ├── .vscode
│ │ │ └── settings.json
│ │ ├── mcp-example-brave-search.md
│ │ ├── mcp-fastmcp-typescript-README.md
│ │ ├── mcp-llms-full.txt
│ │ ├── mcp-metadata-tips.md
│ │ ├── mcp-python-sdk-README.md
│ │ ├── mcp-typescript-sdk-README.md
│ │ ├── pydanticai-documentation.md
│ │ ├── pydanticai-example-question-graph.md
│ │ ├── pydanticai-example-weather.md
│ │ ├── pydanticai-tutorial.md
│ │ └── README.md
│ ├── Makefile
│ ├── mcp-server-bing-search
│ │ ├── .env.example
│ │ ├── .gitignore
│ │ ├── .vscode
│ │ │ ├── launch.json
│ │ │ └── settings.json
│ │ ├── Makefile
│ │ ├── mcp_server_bing_search
│ │ │ ├── __init__.py
│ │ │ ├── config.py
│ │ │ ├── prompts
│ │ │ │ ├── __init__.py
│ │ │ │ ├── clean_website.py
│ │ │ │ └── filter_links.py
│ │ │ ├── server.py
│ │ │ ├── start.py
│ │ │ ├── tools.py
│ │ │ ├── types.py
│ │ │ ├── utils.py
│ │ │ └── web
│ │ │ ├── __init__.py
│ │ │ ├── get_content.py
│ │ │ ├── llm_processing.py
│ │ │ ├── process_website.py
│ │ │ └── search_bing.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ └── test_tools.py
│ │ └── uv.lock
│ ├── mcp-server-bundle
│ │ ├── .vscode
│ │ │ ├── launch.json
│ │ │ └── settings.json
│ │ ├── Makefile
│ │ ├── mcp_server_bundle
│ │ │ ├── __init__.py
│ │ │ └── main.py
│ │ ├── pyinstaller.spec
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ └── uv.lock
│ ├── mcp-server-filesystem
│ │ ├── .env.example
│ │ ├── .github
│ │ │ └── workflows
│ │ │ └── ci.yml
│ │ ├── .gitignore
│ │ ├── .vscode
│ │ │ ├── launch.json
│ │ │ └── settings.json
│ │ ├── Makefile
│ │ ├── mcp_server_filesystem
│ │ │ ├── __init__.py
│ │ │ ├── config.py
│ │ │ ├── server.py
│ │ │ └── start.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ └── test_filesystem.py
│ │ └── uv.lock
│ ├── mcp-server-filesystem-edit
│ │ ├── .env.example
│ │ ├── .gitignore
│ │ ├── .vscode
│ │ │ ├── launch.json
│ │ │ └── settings.json
│ │ ├── data
│ │ │ ├── attachments
│ │ │ │ ├── Daily Game Ideas.txt
│ │ │ │ ├── Frontend Framework Proposal.txt
│ │ │ │ ├── ReDoodle.txt
│ │ │ │ └── Research Template.tex
│ │ │ ├── test_cases.yaml
│ │ │ └── transcripts
│ │ │ ├── transcript_research_simple.md
│ │ │ ├── transcript_Startup_Idea_1_202503031513.md
│ │ │ ├── transcript_Startup_Idea_2_202503031659.md
│ │ │ └── transcript_Web_Frontends_202502281551.md
│ │ ├── Makefile
│ │ ├── mcp_server_filesystem_edit
│ │ │ ├── __init__.py
│ │ │ ├── app_handling
│ │ │ │ ├── __init__.py
│ │ │ │ ├── excel.py
│ │ │ │ ├── miktex.py
│ │ │ │ ├── office_common.py
│ │ │ │ ├── powerpoint.py
│ │ │ │ └── word.py
│ │ │ ├── config.py
│ │ │ ├── evals
│ │ │ │ ├── __init__.py
│ │ │ │ ├── common.py
│ │ │ │ ├── run_comments.py
│ │ │ │ ├── run_edit.py
│ │ │ │ └── run_ppt_edit.py
│ │ │ ├── prompts
│ │ │ │ ├── __init__.py
│ │ │ │ ├── add_comments.py
│ │ │ │ ├── analyze_comments.py
│ │ │ │ ├── latex_edit.py
│ │ │ │ ├── markdown_draft.py
│ │ │ │ ├── markdown_edit.py
│ │ │ │ └── powerpoint_edit.py
│ │ │ ├── server.py
│ │ │ ├── start.py
│ │ │ ├── tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── add_comments.py
│ │ │ │ ├── edit_adapters
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── common.py
│ │ │ │ │ ├── latex.py
│ │ │ │ │ └── markdown.py
│ │ │ │ ├── edit.py
│ │ │ │ └── helpers.py
│ │ │ └── types.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ ├── app_handling
│ │ │ │ ├── test_excel.py
│ │ │ │ ├── test_miktext.py
│ │ │ │ ├── test_office_common.py
│ │ │ │ ├── test_powerpoint.py
│ │ │ │ └── test_word.py
│ │ │ ├── conftest.py
│ │ │ └── tools
│ │ │ └── edit_adapters
│ │ │ ├── test_latex.py
│ │ │ └── test_markdown.py
│ │ └── uv.lock
│ ├── mcp-server-fusion
│ │ ├── .gitignore
│ │ ├── .vscode
│ │ │ ├── launch.json
│ │ │ └── settings.json
│ │ ├── AddInIcon.svg
│ │ ├── config.py
│ │ ├── FusionMCPServerAddIn.manifest
│ │ ├── FusionMCPServerAddIn.py
│ │ ├── mcp_server_fusion
│ │ │ ├── __init__.py
│ │ │ ├── fusion_mcp_server.py
│ │ │ ├── fusion_utils
│ │ │ │ ├── __init__.py
│ │ │ │ ├── event_utils.py
│ │ │ │ ├── general_utils.py
│ │ │ │ └── tool_utils.py
│ │ │ ├── mcp_tools
│ │ │ │ ├── __init__.py
│ │ │ │ ├── fusion_3d_operation.py
│ │ │ │ ├── fusion_geometry.py
│ │ │ │ ├── fusion_pattern.py
│ │ │ │ └── fusion_sketch.py
│ │ │ └── vendor
│ │ │ └── README.md
│ │ ├── README.md
│ │ └── requirements.txt
│ ├── mcp-server-giphy
│ │ ├── .env.example
│ │ ├── .gitignore
│ │ ├── .vscode
│ │ │ ├── launch.json
│ │ │ └── settings.json
│ │ ├── Makefile
│ │ ├── mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── config.py
│ │ │ ├── giphy_search.py
│ │ │ ├── sampling.py
│ │ │ ├── server.py
│ │ │ ├── start.py
│ │ │ └── utils.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ └── uv.lock
│ ├── mcp-server-memory-user-bio
│ │ ├── .env.example
│ │ ├── .gitignore
│ │ ├── .vscode
│ │ │ ├── launch.json
│ │ │ └── settings.json
│ │ ├── Makefile
│ │ ├── mcp_server_memory_user_bio
│ │ │ ├── __init__.py
│ │ │ ├── config.py
│ │ │ ├── server.py
│ │ │ └── start.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ └── uv.lock
│ ├── mcp-server-memory-whiteboard
│ │ ├── .env.example
│ │ ├── .gitignore
│ │ ├── .vscode
│ │ │ ├── launch.json
│ │ │ └── settings.json
│ │ ├── Makefile
│ │ ├── mcp_server_memory_whiteboard
│ │ │ ├── __init__.py
│ │ │ ├── config.py
│ │ │ ├── server.py
│ │ │ └── start.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ └── uv.lock
│ ├── mcp-server-office
│ │ ├── .env.example
│ │ ├── .vscode
│ │ │ ├── launch.json
│ │ │ └── settings.json
│ │ ├── build.sh
│ │ ├── data
│ │ │ ├── attachments
│ │ │ │ ├── Daily Game Ideas.txt
│ │ │ │ ├── Frontend Framework Proposal.txt
│ │ │ │ └── ReDoodle.txt
│ │ │ └── word
│ │ │ ├── test_cases.yaml
│ │ │ └── transcripts
│ │ │ ├── transcript_Startup_Idea_1_202503031513.md
│ │ │ ├── transcript_Startup_Idea_2_202503031659.md
│ │ │ └── transcript_Web_Frontends_202502281551.md
│ │ ├── Makefile
│ │ ├── mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── app_interaction
│ │ │ │ ├── __init__.py
│ │ │ │ ├── excel_editor.py
│ │ │ │ ├── powerpoint_editor.py
│ │ │ │ └── word_editor.py
│ │ │ ├── config.py
│ │ │ ├── constants.py
│ │ │ ├── evals
│ │ │ │ ├── __init__.py
│ │ │ │ ├── common.py
│ │ │ │ ├── run_comment_analysis.py
│ │ │ │ ├── run_feedback.py
│ │ │ │ └── run_markdown_edit.py
│ │ │ ├── helpers.py
│ │ │ ├── markdown_edit
│ │ │ │ ├── __init__.py
│ │ │ │ ├── comment_analysis.py
│ │ │ │ ├── feedback_step.py
│ │ │ │ ├── markdown_edit.py
│ │ │ │ └── utils.py
│ │ │ ├── prompts
│ │ │ │ ├── __init__.py
│ │ │ │ ├── comment_analysis.py
│ │ │ │ ├── feedback.py
│ │ │ │ ├── markdown_draft.py
│ │ │ │ └── markdown_edit.py
│ │ │ ├── server.py
│ │ │ ├── start.py
│ │ │ └── types.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── tests
│ │ │ └── test_word_editor.py
│ │ └── uv.lock
│ ├── mcp-server-open-deep-research
│ │ ├── .env.example
│ │ ├── .gitignore
│ │ ├── .vscode
│ │ │ ├── launch.json
│ │ │ └── settings.json
│ │ ├── Makefile
│ │ ├── mcp_server
│ │ │ ├── __init__.py
│ │ │ ├── config.py
│ │ │ ├── libs
│ │ │ │ └── open_deep_research
│ │ │ │ ├── cookies.py
│ │ │ │ ├── mdconvert.py
│ │ │ │ ├── run_agents.py
│ │ │ │ ├── text_inspector_tool.py
│ │ │ │ ├── text_web_browser.py
│ │ │ │ └── visual_qa.py
│ │ │ ├── open_deep_research.py
│ │ │ ├── server.py
│ │ │ └── start.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ └── uv.lock
│ ├── mcp-server-open-deep-research-clone
│ │ ├── .env.example
│ │ ├── .gitignore
│ │ ├── .vscode
│ │ │ ├── launch.json
│ │ │ └── settings.json
│ │ ├── Makefile
│ │ ├── mcp_server_open_deep_research_clone
│ │ │ ├── __init__.py
│ │ │ ├── azure_openai.py
│ │ │ ├── config.py
│ │ │ ├── logging.py
│ │ │ ├── sampling.py
│ │ │ ├── server.py
│ │ │ ├── start.py
│ │ │ ├── utils.py
│ │ │ └── web_research.py
│ │ ├── pyproject.toml
│ │ ├── README.md
│ │ ├── test
│ │ │ └── test_open_deep_research_clone.py
│ │ └── uv.lock
│ ├── mcp-server-template
│ │ ├── .taplo.toml
│ │ ├── .vscode
│ │ │ └── settings.json
│ │ ├── copier.yml
│ │ ├── README.md
│ │ └── template
│ │ └── {{ project_slug }}
│ │ ├── .env.example.jinja
│ │ ├── .gitignore
│ │ ├── .vscode
│ │ │ ├── launch.json.jinja
│ │ │ └── settings.json
│ │ ├── {{ module_name }}
│ │ │ ├── __init__.py
│ │ │ ├── config.py.jinja
│ │ │ ├── server.py.jinja
│ │ │ └── start.py.jinja
│ │ ├── Makefile.jinja
│ │ ├── pyproject.toml.jinja
│ │ └── README.md.jinja
│ ├── mcp-server-vscode
│ │ ├── .eslintrc.cjs
│ │ ├── .gitignore
│ │ ├── .npmrc
│ │ ├── .vscode
│ │ │ ├── extensions.json
│ │ │ ├── launch.json
│ │ │ ├── settings.json
│ │ │ └── tasks.json
│ │ ├── .vscode-test.mjs
│ │ ├── .vscodeignore
│ │ ├── ASSISTANT_BOOTSTRAP.md
│ │ ├── eslint.config.mjs
│ │ ├── images
│ │ │ └── icon.png
│ │ ├── LICENSE
│ │ ├── Makefile
│ │ ├── out
│ │ │ ├── extension.d.ts
│ │ │ ├── extension.js
│ │ │ ├── test
│ │ │ │ ├── extension.test.d.ts
│ │ │ │ └── extension.test.js
│ │ │ ├── tools
│ │ │ │ ├── code_checker.d.ts
│ │ │ │ ├── code_checker.js
│ │ │ │ ├── debug_tools.d.ts
│ │ │ │ ├── debug_tools.js
│ │ │ │ ├── focus_editor.d.ts
│ │ │ │ ├── focus_editor.js
│ │ │ │ ├── search_symbol.d.ts
│ │ │ │ └── search_symbol.js
│ │ │ └── utils
│ │ │ ├── port.d.ts
│ │ │ └── port.js
│ │ ├── package.json
│ │ ├── pnpm-lock.yaml
│ │ ├── prettier.config.cjs
│ │ ├── README.md
│ │ ├── src
│ │ │ ├── extension.d.ts
│ │ │ ├── extension.ts
│ │ │ ├── test
│ │ │ │ ├── extension.test.d.ts
│ │ │ │ └── extension.test.ts
│ │ │ ├── tools
│ │ │ │ ├── code_checker.d.ts
│ │ │ │ ├── code_checker.ts
│ │ │ │ ├── debug_tools.d.ts
│ │ │ │ ├── debug_tools.ts
│ │ │ │ ├── focus_editor.d.ts
│ │ │ │ ├── focus_editor.ts
│ │ │ │ ├── search_symbol.d.ts
│ │ │ │ └── search_symbol.ts
│ │ │ └── utils
│ │ │ ├── port.d.ts
│ │ │ └── port.ts
│ │ ├── tsconfig.json
│ │ ├── tsconfig.tsbuildinfo
│ │ ├── vsc-extension-quickstart.md
│ │ └── webpack.config.js
│ └── mcp-server-web-research
│ ├── .env.example
│ ├── .gitignore
│ ├── .vscode
│ │ ├── launch.json
│ │ └── settings.json
│ ├── Makefile
│ ├── mcp_server_web_research
│ │ ├── __init__.py
│ │ ├── azure_openai.py
│ │ ├── config.py
│ │ ├── logging.py
│ │ ├── sampling.py
│ │ ├── server.py
│ │ ├── start.py
│ │ ├── utils.py
│ │ └── web_research.py
│ ├── pyproject.toml
│ ├── README.md
│ ├── test
│ │ └── test_web_research.py
│ └── uv.lock
├── README.md
├── RESPONSIBLE_AI_FAQ.md
├── ruff.toml
├── SECURITY.md
├── semantic-workbench.code-workspace
├── SUPPORT.md
├── tools
│ ├── build_ai_context_files.py
│ ├── collect_files.py
│ ├── docker
│ │ ├── azure_website_sshd.conf
│ │ ├── docker-entrypoint.sh
│ │ ├── Dockerfile.assistant
│ │ └── Dockerfile.mcp-server
│ ├── makefiles
│ │ ├── docker-assistant.mk
│ │ ├── docker-mcp-server.mk
│ │ ├── docker.mk
│ │ ├── python.mk
│ │ ├── recursive.mk
│ │ └── shell.mk
│ ├── reset-service-data.ps1
│ ├── reset-service-data.sh
│ ├── run-app.ps1
│ ├── run-app.sh
│ ├── run-canonical-agent.ps1
│ ├── run-canonical-agent.sh
│ ├── run-dotnet-examples-with-aspire.sh
│ ├── run-python-example1.sh
│ ├── run-python-example2.ps1
│ ├── run-python-example2.sh
│ ├── run-service.ps1
│ ├── run-service.sh
│ ├── run-workbench-chatbot.ps1
│ └── run-workbench-chatbot.sh
├── workbench-app
│ ├── .dockerignore
│ ├── .env.example
│ ├── .eslintrc.cjs
│ ├── .gitignore
│ ├── .vscode
│ │ ├── launch.json
│ │ └── settings.json
│ ├── docker-entrypoint.sh
│ ├── Dockerfile
│ ├── docs
│ │ ├── APP_DEV_GUIDE.md
│ │ ├── MESSAGE_METADATA.md
│ │ ├── MESSAGE_TYPES.md
│ │ ├── README.md
│ │ └── STATE_INSPECTORS.md
│ ├── index.html
│ ├── Makefile
│ ├── nginx.conf
│ ├── package.json
│ ├── pnpm-lock.yaml
│ ├── prettier.config.cjs
│ ├── public
│ │ └── assets
│ │ ├── background-1-upscaled.jpg
│ │ ├── background-1-upscaled.png
│ │ ├── background-1.jpg
│ │ ├── background-1.png
│ │ ├── background-2.jpg
│ │ ├── background-2.png
│ │ ├── experimental-feature.jpg
│ │ ├── favicon.svg
│ │ ├── workflow-designer-1.jpg
│ │ ├── workflow-designer-outlets.jpg
│ │ ├── workflow-designer-states.jpg
│ │ └── workflow-designer-transitions.jpg
│ ├── README.md
│ ├── run.sh
│ ├── src
│ │ ├── components
│ │ │ ├── App
│ │ │ │ ├── AppFooter.tsx
│ │ │ │ ├── AppHeader.tsx
│ │ │ │ ├── AppMenu.tsx
│ │ │ │ ├── AppView.tsx
│ │ │ │ ├── CodeLabel.tsx
│ │ │ │ ├── CommandButton.tsx
│ │ │ │ ├── ConfirmLeave.tsx
│ │ │ │ ├── ContentExport.tsx
│ │ │ │ ├── ContentImport.tsx
│ │ │ │ ├── CopyButton.tsx
│ │ │ │ ├── DialogControl.tsx
│ │ │ │ ├── DynamicIframe.tsx
│ │ │ │ ├── ErrorListFromAppState.tsx
│ │ │ │ ├── ErrorMessageBar.tsx
│ │ │ │ ├── ExperimentalNotice.tsx
│ │ │ │ ├── FormWidgets
│ │ │ │ │ ├── BaseModelEditorWidget.tsx
│ │ │ │ │ ├── CustomizedArrayFieldTemplate.tsx
│ │ │ │ │ ├── CustomizedFieldTemplate.tsx
│ │ │ │ │ ├── CustomizedObjectFieldTemplate.tsx
│ │ │ │ │ └── InspectableWidget.tsx
│ │ │ │ ├── LabelWithDescription.tsx
│ │ │ │ ├── Loading.tsx
│ │ │ │ ├── MenuItemControl.tsx
│ │ │ │ ├── MiniControl.tsx
│ │ │ │ ├── MyAssistantServiceRegistrations.tsx
│ │ │ │ ├── MyItemsManager.tsx
│ │ │ │ ├── OverflowMenu.tsx
│ │ │ │ ├── PresenceMotionList.tsx
│ │ │ │ ├── ProfileSettings.tsx
│ │ │ │ └── TooltipWrapper.tsx
│ │ │ ├── Assistants
│ │ │ │ ├── ApplyConfigButton.tsx
│ │ │ │ ├── AssistantAdd.tsx
│ │ │ │ ├── AssistantConfigExportButton.tsx
│ │ │ │ ├── AssistantConfigImportButton.tsx
│ │ │ │ ├── AssistantConfiguration.tsx
│ │ │ │ ├── AssistantConfigure.tsx
│ │ │ │ ├── AssistantCreate.tsx
│ │ │ │ ├── AssistantDelete.tsx
│ │ │ │ ├── AssistantDuplicate.tsx
│ │ │ │ ├── AssistantExport.tsx
│ │ │ │ ├── AssistantImport.tsx
│ │ │ │ ├── AssistantRemove.tsx
│ │ │ │ ├── AssistantRename.tsx
│ │ │ │ ├── AssistantServiceInfo.tsx
│ │ │ │ ├── AssistantServiceMetadata.tsx
│ │ │ │ └── MyAssistants.tsx
│ │ │ ├── AssistantServiceRegistrations
│ │ │ │ ├── AssistantServiceRegistrationApiKey.tsx
│ │ │ │ ├── AssistantServiceRegistrationApiKeyReset.tsx
│ │ │ │ ├── AssistantServiceRegistrationCreate.tsx
│ │ │ │ └── AssistantServiceRegistrationRemove.tsx
│ │ │ ├── Conversations
│ │ │ │ ├── Canvas
│ │ │ │ │ ├── AssistantCanvas.tsx
│ │ │ │ │ ├── AssistantCanvasList.tsx
│ │ │ │ │ ├── AssistantInspector.tsx
│ │ │ │ │ ├── AssistantInspectorList.tsx
│ │ │ │ │ └── ConversationCanvas.tsx
│ │ │ │ ├── ChatInputPlugins
│ │ │ │ │ ├── ClearEditorPlugin.tsx
│ │ │ │ │ ├── LexicalMenu.ts
│ │ │ │ │ ├── ParticipantMentionsPlugin.tsx
│ │ │ │ │ ├── TypeaheadMenuPlugin.css
│ │ │ │ │ └── TypeaheadMenuPlugin.tsx
│ │ │ │ ├── ContentRenderers
│ │ │ │ │ ├── CodeContentRenderer.tsx
│ │ │ │ │ ├── ContentListRenderer.tsx
│ │ │ │ │ ├── ContentRenderer.tsx
│ │ │ │ │ ├── DiffRenderer.tsx
│ │ │ │ │ ├── HtmlContentRenderer.tsx
│ │ │ │ │ ├── JsonSchemaContentRenderer.tsx
│ │ │ │ │ ├── MarkdownContentRenderer.tsx
│ │ │ │ │ ├── MarkdownEditorRenderer.tsx
│ │ │ │ │ ├── MermaidContentRenderer.tsx
│ │ │ │ │ ├── MusicABCContentRenderer.css
│ │ │ │ │ └── MusicABCContentRenderer.tsx
│ │ │ │ ├── ContextWindow.tsx
│ │ │ │ ├── ConversationCreate.tsx
│ │ │ │ ├── ConversationDuplicate.tsx
│ │ │ │ ├── ConversationExport.tsx
│ │ │ │ ├── ConversationFileIcon.tsx
│ │ │ │ ├── ConversationRemove.tsx
│ │ │ │ ├── ConversationRename.tsx
│ │ │ │ ├── ConversationShare.tsx
│ │ │ │ ├── ConversationShareCreate.tsx
│ │ │ │ ├── ConversationShareList.tsx
│ │ │ │ ├── ConversationShareView.tsx
│ │ │ │ ├── ConversationsImport.tsx
│ │ │ │ ├── ConversationTranscript.tsx
│ │ │ │ ├── DebugInspector.tsx
│ │ │ │ ├── FileItem.tsx
│ │ │ │ ├── FileList.tsx
│ │ │ │ ├── InputAttachmentList.tsx
│ │ │ │ ├── InputOptionsControl.tsx
│ │ │ │ ├── InteractHistory.tsx
│ │ │ │ ├── InteractInput.tsx
│ │ │ │ ├── Message
│ │ │ │ │ ├── AttachmentSection.tsx
│ │ │ │ │ ├── ContentRenderer.tsx
│ │ │ │ │ ├── ContentSafetyNotice.tsx
│ │ │ │ │ ├── InteractMessage.tsx
│ │ │ │ │ ├── MessageActions.tsx
│ │ │ │ │ ├── MessageBase.tsx
│ │ │ │ │ ├── MessageBody.tsx
│ │ │ │ │ ├── MessageContent.tsx
│ │ │ │ │ ├── MessageFooter.tsx
│ │ │ │ │ ├── MessageHeader.tsx
│ │ │ │ │ ├── NotificationAccordion.tsx
│ │ │ │ │ └── ToolResultMessage.tsx
│ │ │ │ ├── MessageDelete.tsx
│ │ │ │ ├── MessageLink.tsx
│ │ │ │ ├── MyConversations.tsx
│ │ │ │ ├── MyShares.tsx
│ │ │ │ ├── ParticipantAvatar.tsx
│ │ │ │ ├── ParticipantAvatarGroup.tsx
│ │ │ │ ├── ParticipantItem.tsx
│ │ │ │ ├── ParticipantList.tsx
│ │ │ │ ├── ParticipantStatus.tsx
│ │ │ │ ├── RewindConversation.tsx
│ │ │ │ ├── ShareRemove.tsx
│ │ │ │ ├── SpeechButton.tsx
│ │ │ │ └── ToolCalls.tsx
│ │ │ └── FrontDoor
│ │ │ ├── Chat
│ │ │ │ ├── AssistantDrawer.tsx
│ │ │ │ ├── CanvasDrawer.tsx
│ │ │ │ ├── Chat.tsx
│ │ │ │ ├── ChatCanvas.tsx
│ │ │ │ ├── ChatControls.tsx
│ │ │ │ └── ConversationDrawer.tsx
│ │ │ ├── Controls
│ │ │ │ ├── AssistantCard.tsx
│ │ │ │ ├── AssistantSelector.tsx
│ │ │ │ ├── AssistantServiceSelector.tsx
│ │ │ │ ├── ConversationItem.tsx
│ │ │ │ ├── ConversationList.tsx
│ │ │ │ ├── ConversationListOptions.tsx
│ │ │ │ ├── NewConversationButton.tsx
│ │ │ │ ├── NewConversationForm.tsx
│ │ │ │ └── SiteMenuButton.tsx
│ │ │ ├── GlobalContent.tsx
│ │ │ └── MainContent.tsx
│ │ ├── Constants.ts
│ │ ├── global.d.ts
│ │ ├── index.css
│ │ ├── libs
│ │ │ ├── AppStorage.ts
│ │ │ ├── AuthHelper.ts
│ │ │ ├── EventSubscriptionManager.ts
│ │ │ ├── Theme.ts
│ │ │ ├── useAssistantCapabilities.ts
│ │ │ ├── useChatCanvasController.ts
│ │ │ ├── useConversationEvents.ts
│ │ │ ├── useConversationUtility.ts
│ │ │ ├── useCreateConversation.ts
│ │ │ ├── useDebugComponentLifecycle.ts
│ │ │ ├── useDragAndDrop.ts
│ │ │ ├── useEnvironment.ts
│ │ │ ├── useExportUtility.ts
│ │ │ ├── useHistoryUtility.ts
│ │ │ ├── useKeySequence.ts
│ │ │ ├── useMediaQuery.ts
│ │ │ ├── useMicrosoftGraph.ts
│ │ │ ├── useNotify.tsx
│ │ │ ├── useParticipantUtility.tsx
│ │ │ ├── useSiteUtility.ts
│ │ │ ├── useWorkbenchEventSource.ts
│ │ │ ├── useWorkbenchService.ts
│ │ │ └── Utility.ts
│ │ ├── main.tsx
│ │ ├── models
│ │ │ ├── Assistant.ts
│ │ │ ├── AssistantCapability.ts
│ │ │ ├── AssistantServiceInfo.ts
│ │ │ ├── AssistantServiceRegistration.ts
│ │ │ ├── Config.ts
│ │ │ ├── Conversation.ts
│ │ │ ├── ConversationFile.ts
│ │ │ ├── ConversationMessage.ts
│ │ │ ├── ConversationMessageDebug.ts
│ │ │ ├── ConversationParticipant.ts
│ │ │ ├── ConversationShare.ts
│ │ │ ├── ConversationShareRedemption.ts
│ │ │ ├── ConversationState.ts
│ │ │ ├── ConversationStateDescription.ts
│ │ │ ├── ServiceEnvironment.ts
│ │ │ └── User.ts
│ │ ├── redux
│ │ │ ├── app
│ │ │ │ ├── hooks.ts
│ │ │ │ ├── rtkQueryErrorLogger.ts
│ │ │ │ └── store.ts
│ │ │ └── features
│ │ │ ├── app
│ │ │ │ ├── appSlice.ts
│ │ │ │ └── AppState.ts
│ │ │ ├── chatCanvas
│ │ │ │ ├── chatCanvasSlice.ts
│ │ │ │ └── ChatCanvasState.ts
│ │ │ ├── localUser
│ │ │ │ ├── localUserSlice.ts
│ │ │ │ └── LocalUserState.ts
│ │ │ └── settings
│ │ │ ├── settingsSlice.ts
│ │ │ └── SettingsState.ts
│ │ ├── Root.tsx
│ │ ├── routes
│ │ │ ├── AcceptTerms.tsx
│ │ │ ├── AssistantEditor.tsx
│ │ │ ├── AssistantServiceRegistrationEditor.tsx
│ │ │ ├── Dashboard.tsx
│ │ │ ├── ErrorPage.tsx
│ │ │ ├── FrontDoor.tsx
│ │ │ ├── Login.tsx
│ │ │ ├── Settings.tsx
│ │ │ ├── ShareRedeem.tsx
│ │ │ └── Shares.tsx
│ │ ├── services
│ │ │ └── workbench
│ │ │ ├── assistant.ts
│ │ │ ├── assistantService.ts
│ │ │ ├── conversation.ts
│ │ │ ├── file.ts
│ │ │ ├── index.ts
│ │ │ ├── participant.ts
│ │ │ ├── share.ts
│ │ │ ├── state.ts
│ │ │ └── workbench.ts
│ │ └── vite-env.d.ts
│ ├── tools
│ │ └── filtered-ts-prune.cjs
│ ├── tsconfig.json
│ └── vite.config.ts
└── workbench-service
├── .env.example
├── .vscode
│ ├── extensions.json
│ ├── launch.json
│ └── settings.json
├── alembic.ini
├── devdb
│ ├── docker-compose.yaml
│ └── postgresql-init.sh
├── Dockerfile
├── Makefile
├── migrations
│ ├── env.py
│ ├── README
│ ├── script.py.mako
│ └── versions
│ ├── 2024_09_19_000000_69dcda481c14_init.py
│ ├── 2024_09_19_190029_dffb1d7e219a_file_version_filename.py
│ ├── 2024_09_20_204130_b29524775484_share.py
│ ├── 2024_10_30_231536_039bec8edc33_index_message_type.py
│ ├── 2024_11_04_204029_5149c7fb5a32_conversationmessagedebug.py
│ ├── 2024_11_05_015124_245baf258e11_double_check_debugs.py
│ ├── 2024_11_25_191056_a106de176394_drop_workflow.py
│ ├── 2025_03_19_140136_aaaf792d4d72_set_user_title_set.py
│ ├── 2025_03_21_153250_3763629295ad_add_assistant_template_id.py
│ ├── 2025_05_19_163613_b2f86e981885_delete_context_transfer_assistants.py
│ └── 2025_06_18_174328_503c739152f3_delete_knowlege_transfer_assistants.py
├── pyproject.toml
├── README.md
├── semantic_workbench_service
│ ├── __init__.py
│ ├── api.py
│ ├── assistant_api_key.py
│ ├── auth.py
│ ├── azure_speech.py
│ ├── config.py
│ ├── controller
│ │ ├── __init__.py
│ │ ├── assistant_service_client_pool.py
│ │ ├── assistant_service_registration.py
│ │ ├── assistant.py
│ │ ├── conversation_share.py
│ │ ├── conversation.py
│ │ ├── convert.py
│ │ ├── exceptions.py
│ │ ├── export_import.py
│ │ ├── file.py
│ │ ├── participant.py
│ │ └── user.py
│ ├── db.py
│ ├── event.py
│ ├── files.py
│ ├── logging_config.py
│ ├── middleware.py
│ ├── query.py
│ ├── service_user_principals.py
│ ├── service.py
│ └── start.py
├── tests
│ ├── __init__.py
│ ├── conftest.py
│ ├── docker-compose.yaml
│ ├── test_assistant_api_key.py
│ ├── test_files.py
│ ├── test_integration.py
│ ├── test_middleware.py
│ ├── test_migrations.py
│ ├── test_workbench_service.py
│ └── types.py
└── uv.lock
```
# Files
--------------------------------------------------------------------------------
/workbench-app/src/libs/useAssistantCapabilities.ts:
--------------------------------------------------------------------------------
```typescript
import React from 'react';
import { Assistant } from '../models/Assistant';
import { AssistantCapability } from '../models/AssistantCapability';
import { useWorkbenchService } from './useWorkbenchService';
export function useGetAssistantCapabilities(assistants: Assistant[], skipToken: { skip: boolean } = { skip: false }) {
const [isFetching, setIsFetching] = React.useState<boolean>(true);
// Build a memoized set of all capabilities to be used as a default for assistants that do not
// specify capabilities
const allCapabilities = React.useMemo(
() =>
Object.entries(AssistantCapability).reduce((acc, [_, capability]) => {
acc.add(capability);
return acc;
}, new Set<AssistantCapability>()),
[],
);
const [assistantCapabilities, setAssistantCapabilities] = React.useState<Set<AssistantCapability>>(allCapabilities);
const workbenchService = useWorkbenchService();
// Load the capabilities for all assistants and update the state with the result
React.useEffect(() => {
if (skipToken.skip) {
return;
}
let active = true;
if (assistants.length === 0) {
if (assistantCapabilities.symmetricDifference(allCapabilities).size > 0) {
setAssistantCapabilities(allCapabilities);
}
setIsFetching(false);
return;
}
(async () => {
if (active) {
setIsFetching(true);
}
// Get the service info for each assistant
const infosResponse = await workbenchService.getAssistantServiceInfosAsync(
assistants.map((assistant) => assistant.assistantServiceId),
);
const serviceInfos = infosResponse.filter((info) => info !== undefined);
// Combine all capabilities from all assistants into a single set
const capabilities = serviceInfos.reduce<Set<AssistantCapability>>((acc, info) => {
const metadataCapabilities = info.metadata?.capabilities;
// If there are no capabilities specified at all, default to all capabilities
if (metadataCapabilities === undefined) {
acc.union(allCapabilities);
return acc;
}
const capabilitiesSet = new Set(
Object.keys(metadataCapabilities)
.filter((key) => metadataCapabilities[key])
.map((key) => key as AssistantCapability),
);
acc = acc.union(capabilitiesSet);
return acc;
}, new Set<AssistantCapability>());
if (active) {
if (assistantCapabilities.symmetricDifference(capabilities).size > 0) {
setAssistantCapabilities(capabilities);
}
setIsFetching(false);
}
})();
return () => {
active = false;
};
}, [allCapabilities, assistants, assistantCapabilities, skipToken.skip, workbenchService]);
return {
data: assistantCapabilities,
isFetching,
};
}
```
--------------------------------------------------------------------------------
/workbench-app/docs/STATE_INSPECTORS.md:
--------------------------------------------------------------------------------
```markdown
# State Inspectors
## Overview
State inspectors provide a way to visualize and interact with an assistant's internal state. Each assistant can have multiple state inspectors, with the `config` editor being a required inspector for all assistants.
State inspectors can be used for:
- Debugging assistant behavior
- Monitoring internal state changes
- Providing interactive interfaces for modifying assistant state
- Exposing data and attachments for user inspection
## Accessing State Inspectors
State inspectors are available in the assistant's conversation view. To access them:
1. Join a conversation with an assistant
2. Click the `Show Inspectors` button in the conversation interface
3. A tabbed view will appear with each tab representing a different state
## Rendering Methods
The inspector view will render state based on its content:
1. **Content-based Rendering**: If the state's `data` property contains a `content` key with a string value, it will be rendered as:
- Markdown for formatted text
- HTML for rich content
- Plain text for simple content
2. **Schema-based Rendering**: If the state includes a `JsonSchema` property, a custom UI will be generated based on the schema:
- Form elements will be created for each schema property
- If a `UISchema` property is provided, it will customize the UI appearance
- Validation will follow the schema rules
3. **JSON Fallback**: If neither of the above applies, the state will be rendered as formatted JSON.
## Interactive State Editing
When a state includes a `JsonSchema` property, the inspector provides editing capabilities:
1. An edit button will appear in the inspector
2. Clicking it opens a dialog with form elements based on the schema
3. Users can modify values and save changes
4. Changes are sent to the assistant, which is notified of the update
## Attachments Support
State inspectors can include file attachments:
1. If a state contains `attachments` data, files will be displayed with download options
2. Users can download attachments for local inspection
3. Common file types may have preview capabilities
## Implementing State Inspectors
Assistants can implement state inspectors by:
1. Defining data models with appropriate JSON schemas
2. Exposing state through the assistant service API
3. Handling state change notifications from the user interface
4. Updating state in response to internal events
## Example Schema
```json
{
"JsonSchema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"title": "Name"
},
"enabled": {
"type": "boolean",
"title": "Enabled"
},
"settings": {
"type": "object",
"properties": {
"threshold": {
"type": "number",
"title": "Threshold",
"minimum": 0,
"maximum": 1
}
}
}
}
},
"UISchema": {
"settings": {
"ui:expandable": true
}
},
"data": {
"name": "My Assistant",
"enabled": true,
"settings": {
"threshold": 0.7
}
}
}
```
State inspectors provide powerful debugging and interaction capabilities for both developers and users of the Semantic Workbench platform.
```
--------------------------------------------------------------------------------
/libraries/python/openai-client/openai_client/chat_driver/message_history_providers/tests/formatted_instructions_test.py:
--------------------------------------------------------------------------------
```python
from openai_client.chat_driver import ChatDriver
from openai_client.messages import format_with_liquid
def test_formatted_instructions() -> None:
# Set instructions.
instructions = [
(
"Generate an outline for the document, including title. The outline should include the key points that will"
" be covered in the document. Consider the attachments, the rationale for why they were uploaded, and the"
" conversation that has taken place. The outline should be a hierarchical structure with multiple levels of"
" detail, and it should be clear and easy to understand. The outline should be generated in a way that is"
" consistent with the document that will be generated from it."
),
"<CHAT_HISTORY>{{chat_history}}</CHAT_HISTORY>",
"<ATTACHMENTS>{% for attachment in attachments %}<ATTACHMENT><FILENAME>{{attachment.filename}}</FILENAME><CONTENT>{{attachment.content}}</CONTENT></ATTACHMENT>{% endfor %}</ATTACHMENTS>",
"<EXISTING_OUTLINE>{{outline_versions.last}}</EXISTING_OUTLINE>",
"<USER_FEEDBACK>{{user_feedback}}</USER_FEEDBACK>",
]
# Set vars.
attachments = [
{"filename": "filename1", "content": "content1"},
{"filename": "filename2", "content": "content2"},
]
outline_versions = ["outline1", "outline2"]
user_feedback = "feedback"
chat_history = "history"
formatted_instructions = ChatDriver.format_instructions(
instructions=instructions,
vars={
"attachments": attachments,
"outline_versions": outline_versions,
"user_feedback": user_feedback,
"chat_history": chat_history,
},
formatter=format_with_liquid,
)
expected = [
{
"role": "system",
"content": "Generate an outline for the document, including title. The outline should include the key points that will be covered in the document. Consider the attachments, the rationale for why they were uploaded, and the conversation that has taken place. The outline should be a hierarchical structure with multiple levels of detail, and it should be clear and easy to understand. The outline should be generated in a way that is consistent with the document that will be generated from it.",
},
{"role": "system", "content": "<CHAT_HISTORY>history</CHAT_HISTORY>"},
# {
# "role": "system",
# "content": "<ATTACHMENT><FILENAME>filename1</FILENAME><CONTENT>content1</CONTENT></ATTACHMENT>",
# },
# {
# "role": "system",
# "content": "<ATTACHMENT><FILENAME>filename2</FILENAME><CONTENT>content2</CONTENT></ATTACHMENT>",
# },
{
"role": "system",
"content": "<ATTACHMENTS><ATTACHMENT><FILENAME>filename1</FILENAME><CONTENT>content1</CONTENT></ATTACHMENT><ATTACHMENT><FILENAME>filename2</FILENAME><CONTENT>content2</CONTENT></ATTACHMENT></ATTACHMENTS>",
},
{"role": "system", "content": "<EXISTING_OUTLINE>outline2</EXISTING_OUTLINE>"},
{"role": "system", "content": "<USER_FEEDBACK>feedback</USER_FEEDBACK>"},
]
assert formatted_instructions == expected
```
--------------------------------------------------------------------------------
/assistants/project-assistant/assistant/agentic/create_invitation.py:
--------------------------------------------------------------------------------
```python
from typing import Any
import openai_client
from semantic_workbench_assistant.assistant_app import ConversationContext
from assistant.config import assistant_config
from assistant.domain.share_manager import ShareManager
from assistant.logging import convert_to_serializable, logger
from assistant.notifications import Notifications
from assistant.prompt_utils import (
ContextSection,
ContextStrategy,
Instructions,
Prompt,
add_context_to_prompt,
)
from assistant.utils import load_text_include
async def create_invitation(context: ConversationContext) -> str:
debug: dict[str, Any] = {
"context": convert_to_serializable(context.to_dict()),
}
config = await assistant_config.get(context.assistant)
# Set up prompt instructions.
instruction_text = load_text_include("create_invitation.md")
instructions = Instructions(instruction_text)
prompt = Prompt(
instructions=instructions,
context_strategy=ContextStrategy.MULTI,
)
# Add prompt context.
role = await ShareManager.get_conversation_role(context)
await add_context_to_prompt(
prompt,
context=context,
role=role,
model=config.request_config.openai_model,
token_limit=config.request_config.max_tokens,
attachments_config=config.attachments_config,
attachments_in_system_message=True,
include=[
ContextSection.KNOWLEDGE_INFO,
ContextSection.KNOWLEDGE_BRIEF,
# ContextSection.TASKS,
ContextSection.TARGET_AUDIENCE,
# ContextSection.LEARNING_OBJECTIVES,
ContextSection.KNOWLEDGE_DIGEST,
# ContextSection.INFORMATION_REQUESTS,
# ContextSection.SUGGESTED_NEXT_ACTIONS,
ContextSection.COORDINATOR_CONVERSATION,
ContextSection.ATTACHMENTS,
],
)
# Chat completion
async with openai_client.create_client(config.service_config) as client:
try:
completion_args = {
"messages": prompt.messages(),
"model": config.request_config.openai_model,
"max_tokens": 500,
"temperature": 0.8,
}
debug["completion_args"] = openai_client.serializable(completion_args)
# LLM call
response = await client.chat.completions.create(
**completion_args,
)
openai_client.validate_completion(response)
debug["completion_response"] = openai_client.serializable(response.model_dump())
# Response
if response and response.choices and response.choices[0].message.content:
output: str = response.choices[0].message.content
if output:
await Notifications.notify(context, f"Generated invitation.\n\n{output}", debug_data=debug)
return output
else:
logger.warning("Empty response from LLM while generating invitation.")
except Exception as e:
logger.exception(f"Failed to make OpenIA call: {e}")
debug["error"] = str(e)
# logger.debug(f"{__name__}: {debug}")
return "Failed to generate invitation."
```
--------------------------------------------------------------------------------
/assistants/navigator-assistant/assistant/response/utils/openai_utils.py:
--------------------------------------------------------------------------------
```python
# Copyright (c) Microsoft. All rights reserved.
import logging
from typing import List, Literal, Union
from assistant_extensions.ai_clients.config import AzureOpenAIClientConfigModel, OpenAIClientConfigModel
from openai import AsyncOpenAI, NotGiven
from openai.types.chat import (
ChatCompletion,
ChatCompletionMessageParam,
ChatCompletionToolParam,
ParsedChatCompletion,
)
from openai_client import AzureOpenAIServiceConfig, OpenAIRequestConfig, OpenAIServiceConfig
from pydantic import BaseModel
from ...config import AssistantConfigModel
logger = logging.getLogger(__name__)
def get_ai_client_configs(
config: AssistantConfigModel, request_type: Literal["generative", "reasoning"] = "generative"
) -> Union[AzureOpenAIClientConfigModel, OpenAIClientConfigModel]:
def create_ai_client_config(
service_config: AzureOpenAIServiceConfig | OpenAIServiceConfig,
request_config: OpenAIRequestConfig,
) -> AzureOpenAIClientConfigModel | OpenAIClientConfigModel:
if isinstance(service_config, AzureOpenAIServiceConfig):
return AzureOpenAIClientConfigModel(
service_config=service_config,
request_config=request_config,
)
return OpenAIClientConfigModel(
service_config=service_config,
request_config=request_config,
)
if request_type == "reasoning":
return create_ai_client_config(
config.reasoning_ai_client_config.service_config,
config.reasoning_ai_client_config.request_config,
)
return create_ai_client_config(
config.generative_ai_client_config.service_config,
config.generative_ai_client_config.request_config,
)
async def get_completion(
client: AsyncOpenAI,
request_config: OpenAIRequestConfig,
chat_message_params: List[ChatCompletionMessageParam],
tools: List[ChatCompletionToolParam],
) -> ParsedChatCompletion[BaseModel] | ChatCompletion:
"""
Generate a completion from the OpenAI API.
"""
completion_args = {
"messages": chat_message_params,
"model": request_config.model,
}
if request_config.is_reasoning_model:
# reasoning models
completion_args["max_completion_tokens"] = request_config.response_tokens
completion_args["reasoning_effort"] = request_config.reasoning_effort
else:
# all other models
completion_args["max_tokens"] = request_config.response_tokens
# list of models that do not support tools
no_tools_support = ["o1-preview", "o1-mini"]
no_parallel_tool_calls = ["o3-mini"]
# add tools to completion args if model supports tools
if request_config.model not in no_tools_support:
completion_args["tools"] = tools or NotGiven()
if tools:
completion_args["tool_choice"] = "auto"
if request_config.model not in no_parallel_tool_calls:
completion_args["parallel_tool_calls"] = False
logger.debug(
"Initiating OpenAI request: %s for '%s' with %d messages",
client.base_url,
request_config.model,
len(chat_message_params),
)
completion = await client.chat.completions.create(**completion_args)
return completion
```
--------------------------------------------------------------------------------
/mcp-servers/mcp-server-fusion/FusionMCPServerAddIn.py:
--------------------------------------------------------------------------------
```python
import atexit
import threading
import signal
import logging
from .mcp_server_fusion.fusion_mcp_server import FusionMCPServer
from .mcp_server_fusion.fusion_utils import log, handle_error
class FusionMCPAddIn:
def __init__(self, port: int = 6050, show_errors: bool = True):
self.port = port
self.show_errors = show_errors
self.server = None
self.server_thread = None
self.shutdown_event = threading.Event()
self.logger = logging.getLogger(__name__)
def start(self):
"""Start the MCP server in a background thread"""
if self.server_thread and self.server_thread.is_alive():
return
try:
log('Starting MCP Server add-in')
# Create server instance
self.server = FusionMCPServer(self.port)
# Start server in background thread
self.server_thread = threading.Thread(
target=self._run_server,
daemon=True,
name="MCPServerThread"
)
self.server_thread.start()
# Set up signal handlers
signal.signal(signal.SIGTERM, lambda sig, frame: self.stop())
atexit.register(self.stop)
log('MCP Server add-in started successfully')
except Exception as e:
handle_error('start', self.show_errors)
self.logger.error(f'Failed to start add-in: {str(e)}')
self.stop()
def _run_server(self):
"""Run the server in the background thread"""
try:
log('Starting MCP server thread')
if self.server:
self.server.start()
log('MCP server thread stopping')
except Exception as e:
if not self.shutdown_event.is_set():
handle_error('_run_server', self.show_errors)
self.logger.error(f'Error in server thread: {str(e)}')
finally:
self.shutdown_event.set()
def stop(self):
"""Stop the MCP server and clean up resources"""
if self.shutdown_event.is_set():
return
try:
log('Stopping MCP Server add-in')
self.shutdown_event.set()
# Stop server
if self.server:
self.server.shutdown()
self.server = None
log('MCP server stopped')
# Wait for thread to finish
if self.server_thread and self.server_thread.is_alive():
self.server_thread.join(timeout=5)
self.server_thread = None
log('Server thread stopped')
log('MCP Server add-in stopped')
except Exception as e:
handle_error('stop', self.show_errors)
self.logger.error(f'Error stopping add-in: {str(e)}')
# Global add-in instance
_addin = None
def run(context):
"""Add-in entry point"""
global _addin
if _addin is None:
_addin = FusionMCPAddIn()
_addin.start()
def stop(context):
"""Add-in cleanup point"""
global _addin
if _addin is not None:
_addin.stop()
_addin = None
```
--------------------------------------------------------------------------------
/aspire-orchestrator/Aspire.Extensions/UvAppHostingExtensions.cs:
--------------------------------------------------------------------------------
```csharp
// Copyright (c) Microsoft. All rights reserved.
using Aspire.Hosting.ComponentModel;
using Aspire.Hosting.Extensions;
namespace Aspire.Hosting;
public static class UvAppHostingExtensions
{
public static IResourceBuilder<UvAppResource> AddUvApp(
this IDistributedApplicationBuilder builder,
string name,
string projectDirectory,
string scriptPath,
params string[] scriptArgs)
{
ArgumentNullException.ThrowIfNull(builder);
return builder.AddUvApp(name, scriptPath, projectDirectory, ".venv", scriptArgs);
}
private static IResourceBuilder<UvAppResource> AddUvApp(this IDistributedApplicationBuilder builder,
string name,
string scriptPath,
string? projectDirectory,
string virtualEnvironmentPath,
params string[] args)
{
ArgumentNullException.ThrowIfNull(builder);
ArgumentNullException.ThrowIfNull(name);
ArgumentNullException.ThrowIfNull(scriptPath);
string wd = projectDirectory ?? Path.Combine("..", name);
projectDirectory = Path.Combine(builder.AppHostDirectory, wd).NormalizePathForCurrentPlatform();
var virtualEnvironment = new VirtualEnvironment(Path.IsPathRooted(virtualEnvironmentPath)
? virtualEnvironmentPath
: Path.Join(projectDirectory, virtualEnvironmentPath));
var instrumentationExecutable = virtualEnvironment.GetExecutable("opentelemetry-instrument");
// var pythonExecutable = virtualEnvironment.GetRequiredExecutable("python");
// var projectExecutable = instrumentationExecutable ?? pythonExecutable;
string[] allArgs = args is { Length: > 0 }
? ["run", "--frozen", scriptPath, .. args]
: ["run", "--frozen", scriptPath];
var projectResource = new UvAppResource(name, projectDirectory);
var resourceBuilder = builder.AddResource(projectResource)
.WithArgs(allArgs)
.WithArgs(context =>
{
// If the project is to be automatically instrumented, add the instrumentation executable arguments first.
if (!string.IsNullOrEmpty(instrumentationExecutable))
{
AddOpenTelemetryArguments(context);
// // Add the python executable as the next argument so we can run the project.
// context.Args.Add(pythonExecutable!);
}
});
if (!string.IsNullOrEmpty(instrumentationExecutable))
{
resourceBuilder.WithOtlpExporter();
// Make sure to attach the logging instrumentation setting, so we can capture logs.
// Without this you'll need to configure logging yourself. Which is kind of a pain.
resourceBuilder.WithEnvironment("OTEL_PYTHON_LOGGING_AUTO_INSTRUMENTATION_ENABLED", "true");
}
return resourceBuilder;
}
private static void AddOpenTelemetryArguments(CommandLineArgsCallbackContext context)
{
context.Args.Add("--traces_exporter");
context.Args.Add("otlp");
context.Args.Add("--logs_exporter");
context.Args.Add("console,otlp");
context.Args.Add("--metrics_exporter");
context.Args.Add("otlp");
}
}
```
--------------------------------------------------------------------------------
/libraries/python/skills/skill-library/skill_library/skills/fabric/patterns/analyze_debate/system.md:
--------------------------------------------------------------------------------
```markdown
# IDENTITY and PURPOSE
You are a neutral and objective entity whose sole purpose is to help humans understand debates to broaden their own views.
You will be provided with the transcript of a debate.
Take a deep breath and think step by step about how to best accomplish this goal using the following steps.
# STEPS
- Consume the entire debate and think deeply about it.
- Map out all the claims and implications on a virtual whiteboard in your mind.
- Analyze the claims from a neutral and unbiased perspective.
# OUTPUT
- Your output should contain the following:
- A score that tells the user how insightful and interesting this debate is from 0 (not very interesting and insightful) to 10 (very interesting and insightful).
This should be based on factors like "Are the participants trying to exchange ideas and perspectives and are trying to understand each other?", "Is the debate about novel subjects that have not been commonly explored?" or "Have the participants reached some agreement?".
Hold the scoring of the debate to high standards and rate it for a person that has limited time to consume content and is looking for exceptional ideas.
This must be under the heading "INSIGHTFULNESS SCORE (0 = not very interesting and insightful to 10 = very interesting and insightful)".
- A rating of how emotional the debate was from 0 (very calm) to 5 (very emotional). This must be under the heading "EMOTIONALITY SCORE (0 (very calm) to 5 (very emotional))".
- A list of the participants of the debate and a score of their emotionality from 0 (very calm) to 5 (very emotional). This must be under the heading "PARTICIPANTS".
- A list of arguments attributed to participants with names and quotes. If possible, this should include external references that disprove or back up their claims.
It is IMPORTANT that these references are from trusted and verifiable sources that can be easily accessed. These sources have to BE REAL and NOT MADE UP. This must be under the heading "ARGUMENTS".
If possible, provide an objective assessment of the truth of these arguments. If you assess the truth of the argument, provide some sources that back up your assessment. The material you provide should be from reliable, verifiable, and trustworthy sources. DO NOT MAKE UP SOURCES.
- A list of agreements the participants have reached, attributed with names and quotes. This must be under the heading "AGREEMENTS".
- A list of disagreements the participants were unable to resolve and the reasons why they remained unresolved, attributed with names and quotes. This must be under the heading "DISAGREEMENTS".
- A list of possible misunderstandings and why they may have occurred, attributed with names and quotes. This must be under the heading "POSSIBLE MISUNDERSTANDINGS".
- A list of learnings from the debate. This must be under the heading "LEARNINGS".
- A list of takeaways that highlight ideas to think about, sources to explore, and actionable items. This must be under the heading "TAKEAWAYS".
# OUTPUT INSTRUCTIONS
- Output all sections above.
- Use Markdown to structure your output.
- When providing quotes, these quotes should clearly express the points you are using them for. If necessary, use multiple quotes.
# INPUT:
INPUT:
```
--------------------------------------------------------------------------------
/mcp-servers/mcp-server-vscode/src/tools/search_symbol.ts:
--------------------------------------------------------------------------------
```typescript
import * as vscode from 'vscode';
import { focusEditorTool } from './focus_editor';
export async function searchSymbolTool({
query,
useDefinition = true,
maxResults = 50,
openFile = false, // Optional: Open files after search
}: {
query: string;
useDefinition?: boolean;
maxResults?: number;
openFile?: boolean;
}) {
const results: {
definition: {
file: string;
startLine: number;
startColumn: number;
endLine: number;
endColumn: number;
snippet: string;
} | null;
globalSearch: Array<{ file: string; line: number; snippet: string }>;
} = { definition: null, globalSearch: [] };
// Try "Go to Definition"
if (useDefinition && vscode.window.activeTextEditor) {
const editor = vscode.window.activeTextEditor;
const position = editor.selection.active;
const uri = editor.document.uri;
const definitionResults = await vscode.commands.executeCommand<vscode.Location[]>(
'vscode.executeDefinitionProvider',
uri,
position,
);
if (definitionResults && definitionResults.length > 0) {
const def = definitionResults[0];
results.definition = {
file: def.uri.fsPath,
startLine: def.range.start.line,
startColumn: def.range.start.character,
endLine: def.range.end.line,
endColumn: def.range.end.character,
snippet: def.range.start.line === def.range.end.line ? editor.document.getText(def.range) : '',
};
// Reuse `focusEditorTool` if applicable
if (openFile) {
await focusEditorTool({
filePath: def.uri.fsPath,
startLine: def.range.start.line,
startColumn: def.range.start.character,
endLine: def.range.end.line,
endColumn: def.range.end.character,
});
}
}
}
// Perform a global text search
const globalSearchResults: Array<any> = [];
await vscode.commands.executeCommand<{ uri: vscode.Uri; ranges: vscode.Range[]; preview: { text: string } }[]>(
'vscode.executeWorkspaceSymbolProvider',
query,
({ uri, ranges, preview }: { uri: vscode.Uri; ranges: vscode.Range[]; preview: { text: string } }) => {
const match = {
file: uri.fsPath,
line: ranges[0].start.line,
snippet: preview.text.trim(),
};
if (globalSearchResults.length < maxResults) {
globalSearchResults.push({
file: match.file, // Correct the key to 'file'
line: match.line, // Correct key/logic
snippet: match.snippet, // Correct key/logic
});
}
},
);
results.globalSearch = globalSearchResults;
// Open the first global search result if requested
if (openFile && globalSearchResults.length > 0) {
const firstMatch = globalSearchResults[0];
await focusEditorTool({ filePath: firstMatch.file, line: firstMatch.line, column: 0 });
}
return results;
}
```
--------------------------------------------------------------------------------
/mcp-servers/mcp-server-filesystem-edit/tests/app_handling/test_powerpoint.py:
--------------------------------------------------------------------------------
```python
# Copyright (c) Microsoft. All rights reserved.
import sys
from pathlib import Path
import pytest
from mcp_server_filesystem_edit.app_handling.office_common import OfficeAppType, open_document_in_office
from mcp_server_filesystem_edit.app_handling.powerpoint import (
get_markdown_representation,
write_markdown,
)
@pytest.fixture(autouse=True)
def check_for_win():
if sys.platform != "win32":
pytest.skip("This test is only applicable on Windows.")
@pytest.fixture
def powerpoint_document(ppt_file_path: Path):
"""Fixture that provides an active PowerPoint document."""
_, doc = open_document_in_office(ppt_file_path, OfficeAppType.POWERPOINT)
yield doc
def markdown_roundtrip_helper(powerpoint_document, markdown_text: str) -> str:
"""
Helper function that performs a roundtrip test:
1. Writes markdown to a PowerPoint document
2. Reads it back as markdown
3. Writes the read markdown back to the document
"""
write_markdown(powerpoint_document, markdown_text)
rt_markdown_text = get_markdown_representation(powerpoint_document)
write_markdown(powerpoint_document, rt_markdown_text)
return rt_markdown_text
def test_title_and_content(powerpoint_document):
markdown_text = """<slide index="3" layout="title_and_content">
<title>Key Points</title>
<content>
## Main Ideas
- First important point
- Second important point
- Third important point with **bold text** in the middle
## Additional Information
1. Numbered item one
2. Numbered item two with *italic text*
</content>
</slide>"""
markdown_roundtrip_helper(powerpoint_document, markdown_text)
def test_formatting(powerpoint_document):
markdown_text = """<slide index="3" layout="title_and_content">
<title>Key Points</title>
<content>
important point with **bold text** in the middle
</content>
</slide>"""
markdown_roundtrip_helper(powerpoint_document, markdown_text)
def test_section_header(powerpoint_document):
markdown_text = """<slide index="1" layout="section_header">
<title>Agenda</title>
<content>
What we'll cover today
</content>
</slide>"""
markdown_roundtrip_helper(powerpoint_document, markdown_text)
def test_title(powerpoint_document):
markdown_text = """<slide index="3" layout="title">
<title>Presentation Title</title>
<content>By **John** Smith</content>
</slide>"""
markdown_roundtrip_helper(powerpoint_document, markdown_text)
def test_basic_presentation_content(powerpoint_document):
markdown_text = """<slide index="1" layout="title">
<title>Presentation Title</title>
<content>By John Smith</content>
</slide>
<slide index="2" layout="section_header">
<title>Agenda</title>
<content>
What we'll cover today
</content>
</slide>
<slide index="3" layout="title_and_content">
<title>Key Points</title>
<content>
## Main Ideas
- First important point
- Second important point
- Third important point with **bold text**
## Additional Information
1. Numbered item one
2. Numbered item two with *italic text*
</content>
</slide>
<slide index="4" layout="two_content">
<title>Comparison</title>
<content>
### Option A
- Feature 1
- Feature 2
- Feature 3
</content>
<content>
### Option B
- Alternative 1
- Alternative 2
- ***Important note***
</content>
</slide>
"""
markdown_roundtrip_helper(powerpoint_document, markdown_text)
```
--------------------------------------------------------------------------------
/libraries/python/skills/skill-library/skill_library/skills/research/routines/update_research_plan.py:
--------------------------------------------------------------------------------
```python
from typing import Any, cast
from openai_client import (
CompletionError,
create_system_message,
create_user_message,
extra_data,
make_completion_args_serializable,
validate_completion,
)
from pydantic import BaseModel
from skill_library import AskUserFn, EmitFn, RunContext, RunRoutineFn
from skill_library.logging import logger
from skill_library.skills.research import ResearchSkill
async def main(
context: RunContext,
routine_state: dict[str, Any],
emit: EmitFn,
run: RunRoutineFn,
ask_user: AskUserFn,
topic: str,
plan: str,
) -> list[str]:
"""
Update a research plan using information from a conversation. The plan will
consist of an updated set of research questions to be answered.
"""
research_skill = cast(ResearchSkill, context.skills["research"])
language_model = research_skill.config.language_model
class Output(BaseModel):
reasoning: str
research_questions: list[str]
completion_args = {
"model": "gpt-4o",
"messages": [
create_system_message(
(
"You are an expert research assistant. You have previously considered a topic and carefully analyzed it to identify core, tangential, and nuanced areas requiring exploration. You approached the topic methodically, breaking it down into its fundamental aspects, associated themes, and interconnections. You thoroughly thought through the subject step by step and created a comprehensive set of research questions. These questions were presented to the user, who has now provided additional information. Use this information, found in the chat history to update the research plan. Don't entirely rewrite the plan unless the user asks you to, just tweak it.\n"
"\n---\n\n"
"The topic is: {topic}\n"
"\n---\n\n"
"The research questions we are updating:\n\n"
"{plan}\n\n"
)
),
create_user_message(
f"Chat history: {(await context.conversation_history()).model_dump_json()}",
),
],
"response_format": Output,
}
logger.debug("Completion call.", extra=extra_data(make_completion_args_serializable(completion_args)))
metadata = {}
metadata["completion_args"] = make_completion_args_serializable(completion_args)
try:
completion = await language_model.beta.chat.completions.parse(
**completion_args,
)
validate_completion(completion)
logger.debug("Completion response.", extra=extra_data({"completion": completion.model_dump()}))
metadata["completion"] = completion.model_dump()
except Exception as e:
completion_error = CompletionError(e)
metadata["completion_error"] = completion_error.message
logger.error(
completion_error.message,
extra=extra_data({"completion_error": completion_error.body}),
)
raise completion_error from e
else:
research_questions = cast(Output, completion.choices[0].message.parsed).research_questions
metadata["research_questions"] = research_questions
return research_questions
finally:
context.log("update_research_plan", metadata)
```
--------------------------------------------------------------------------------
/workbench-app/src/components/Assistants/MyAssistants.tsx:
--------------------------------------------------------------------------------
```typescript
// Copyright (c) Microsoft. All rights reserved.
import { Bot24Regular } from '@fluentui/react-icons';
import React from 'react';
import { Assistant } from '../../models/Assistant';
import { useGetAssistantsQuery } from '../../services/workbench';
import { CommandButton } from '../App/CommandButton';
import { MiniControl } from '../App/MiniControl';
import { MyItemsManager } from '../App/MyItemsManager';
import { AssistantCreate } from './AssistantCreate';
import { AssistantDelete } from './AssistantDelete';
import { AssistantDuplicate } from './AssistantDuplicate';
import { AssistantExport } from './AssistantExport';
import { AssistantImport } from './AssistantImport';
interface MyAssistantsProps {
assistants?: Assistant[];
title?: string;
hideInstruction?: boolean;
onCreate?: (assistant: Assistant) => void;
}
export const MyAssistants: React.FC<MyAssistantsProps> = (props) => {
const { assistants, title, hideInstruction, onCreate } = props;
const { refetch: refetchAssistants } = useGetAssistantsQuery();
const [assistantCreateOpen, setAssistantCreateOpen] = React.useState(false);
const handleAssistantCreate = async (assistant: Assistant) => {
await refetchAssistants();
onCreate?.(assistant);
};
const handleAssistantImport = async (result: { assistantIds: string[]; conversationIds: string[] }) => {
(await refetchAssistants().unwrap())
.filter((assistant) => result.assistantIds.includes(assistant.id))
.forEach((assistant) => onCreate?.(assistant));
};
return (
<MyItemsManager
items={assistants
?.toSorted((a, b) => a.name.localeCompare(b.name))
.map((assistant) => (
<MiniControl
key={assistant.id}
icon={<Bot24Regular />}
label={assistant?.name}
linkUrl={`/assistant/${encodeURIComponent(assistant.id)}/edit`}
actions={
<>
<AssistantExport assistantId={assistant.id} iconOnly />
<AssistantDuplicate assistant={assistant} iconOnly />
<AssistantDelete assistant={assistant} iconOnly />
</>
}
/>
))}
title={title ?? 'My Assistants'}
itemLabel="Assistant"
hideInstruction={hideInstruction}
actions={
<>
<CommandButton
icon={<Bot24Regular />}
label={`New Assistant`}
description={`Select an assistant service and create a new assistant instance`}
onClick={() => setAssistantCreateOpen(true)}
/>
<AssistantCreate
open={assistantCreateOpen}
onOpenChange={(open) => setAssistantCreateOpen(open)}
onCreate={handleAssistantCreate}
onImport={handleAssistantImport}
/>
<AssistantImport onImport={handleAssistantImport} />
</>
}
/>
);
};
```
--------------------------------------------------------------------------------
/libraries/python/skills/skill-library/skill_library/logging.py:
--------------------------------------------------------------------------------
```python
import json
import logging
from datetime import datetime
from os import PathLike
from pathlib import Path
from typing import Any
from uuid import UUID
from pydantic import BaseModel
logger = logging.getLogger("skill-library")
logger.addHandler(logging.NullHandler())
logger.setLevel(logging.DEBUG)
def convert_to_serializable(data: Any) -> Any:
"""
Recursively convert Pydantic BaseModel instances to dictionaries.
"""
if isinstance(data, BaseModel):
return data.model_dump()
elif isinstance(data, dict):
return {key: convert_to_serializable(value) for key, value in data.items()}
elif isinstance(data, list):
return [convert_to_serializable(item) for item in data]
elif isinstance(data, tuple):
return tuple(convert_to_serializable(item) for item in data)
elif isinstance(data, set):
return {convert_to_serializable(item) for item in data}
return data
class CustomEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, UUID):
return str(o)
if isinstance(o, datetime):
return o.isoformat()
return super().default(o)
def extra_data(data: Any) -> dict[str, Any]:
"""
Helper function to use when adding extra data to log messages.
"""
extra = {}
# Convert to serializable.
data = convert_to_serializable(data)
# Ensure data is a JSON-serializable object.
try:
data = json.loads(json.dumps(data, cls=CustomEncoder))
except Exception as e:
data = str(e)
if data:
extra["data"] = data
return extra
extra_data = extra_data
class JsonFormatter(logging.Formatter):
def format(self, record) -> str:
record_dict = record.__dict__
log_record = {
"timestamp": self.formatTime(record, self.datefmt),
"level": record.levelname,
"sessionId": record_dict.get("session_id", None),
"runIdd": record_dict.get("run_id", None),
"message": record.getMessage(),
"data": record_dict.get("data", None),
"module": record.module,
"functionName": record.funcName,
"lineNumber": record.lineno,
"logger": record.name,
}
extra_fields = {
key: value
for key, value in record.__dict__.items()
if key
not in [
"levelname",
"msg",
"args",
"funcName",
"module",
"lineno",
"name",
"message",
"asctime",
"session_id",
"run_id",
"data",
]
}
log_record.update(extra_fields)
return json.dumps(log_record)
def file_logging_handler(logfile_path: PathLike, ensure_dir_exists: bool = False) -> logging.FileHandler:
# Create the data directory if it does not exist.
data_dir = Path(logfile_path).parent
if ensure_dir_exists:
if not data_dir.exists():
data_dir.mkdir()
else:
if not data_dir.exists():
raise FileNotFoundError(f"Logging directory {data_dir} does not exist.")
file_handler = logging.FileHandler(Path(logfile_path))
file_handler.setFormatter(JsonFormatter())
return file_handler
```
--------------------------------------------------------------------------------
/mcp-servers/mcp-server-vscode/package.json:
--------------------------------------------------------------------------------
```json
{
"name": "mcp-server-vscode",
"displayName": "VSCode MCP Server",
"publisher": "SemanticWorkbenchTeam",
"description": "VSCode tools and resources as a Model Context Protocol (MCP) server in a VSCode extension.",
"version": "0.0.9",
"type": "commonjs",
"icon": "images/icon.png",
"engines": {
"vscode": "^1.96.0"
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/semanticworkbench"
},
"categories": [
"Other"
],
"activationEvents": [
"onStartupFinished"
],
"contributes": {
"commands": [
{
"command": "mcpServer.stopServer",
"title": "MCP Server: Stop Server"
},
{
"command": "mcpServer.startServer",
"title": "MCP Server: Start Server"
},
{
"command": "mcpServer.setPort",
"title": "MCP Server: Set Port"
}
],
"configuration": {
"type": "object",
"properties": {
"mcpServer.startOnActivate": {
"type": "boolean",
"default": true,
"description": "Determines if the MCP Server should start automatically on VSCode activation."
},
"mcpServer.port": {
"type": "number",
"default": 6010,
"description": "The port that the MCP Server listens on. Set in case of conflicts or custom configurations."
}
}
}
},
"main": "./dist/extension.js",
"scripts": {
"vscode:prepublish": "pnpm run package",
"compile": "webpack",
"watch": "webpack --watch",
"package": "webpack --mode production --devtool hidden-source-map",
"compile-tests": "tsc -p . --outDir out",
"package-extension": "cross-env npm_config_user_agent=pnpm vsce package",
"watch-tests": "tsc -p . -w --outDir out",
"pretest": "pnpm run compile-tests && pnpm run compile && pnpm run lint",
"lint": "eslint src",
"test": "vscode-test"
},
"devDependencies": {
"@types/express": "^5.0.0",
"@types/mocha": "^10.0.10",
"@types/node": "~22.13.1",
"@types/vscode": "^1.96.0",
"@typescript-eslint/eslint-plugin": "^8.22.0",
"@typescript-eslint/parser": "^8.22.0",
"@vscode/test-cli": "^0.0.10",
"@vscode/test-electron": "^2.4.1",
"@vscode/vsce": "^3.2.2",
"cross-env": "^7.0.3",
"eslint": "^9.19.0",
"eslint-plugin-import": "^2.31.0",
"prettier": "^2.8.8",
"ts-loader": "^9.5.2",
"typescript": "^5.7.3",
"webpack": "^5.97.1",
"webpack-cli": "^6.0.1"
},
"dependencies": {
"@modelcontextprotocol/sdk": "^1.4.1",
"dedent": "^1.5.3",
"express": "^4.21.2",
"get-port": "^7.1.0"
},
"eslintConfig": {
"plugins": [
"prettier"
],
"rules": {
"prettier/prettier": "error"
}
},
"packageManager": "[email protected]+sha512.0486e394640d3c1fb3c9d43d49cf92879ff74f8516959c235308f5a8f62e2e19528a65cdc2a3058f587cde71eba3d5b56327c8c33a97e4c4051ca48a10ca2d5f"
}
```
--------------------------------------------------------------------------------
/assistants/knowledge-transfer-assistant/docs/how-kta-works.md:
--------------------------------------------------------------------------------
```markdown
# Understanding how the Knowledge Transfer Assistant
The Knowledge Transfer Assistant isn't simply a chat conversation with an assistant.
It uses a "more code than model", recipe-inspired approach that runs "meta-cognitive operations" to create an assistant that guides users through the knowledge transfer process.
The Knowledge Transfer Assistant is an assistant experience that runs within _MADE: Exploration's_ Semantic Workbench.
## How it works
The Knowledge Transfer Assistant uses a multi-conversation architecture to separate knowledge creation from knowledge consumption, addressing the confusion that arises when multiple participants work in the same shared conversation.
### Dual-Conversation Architecture
The system operates through two conversation types:
1. **Coordinator Conversation**: Where knowledge creators collaborate to structure and package their knowledge
2. **Team Conversations**: Individual conversations created for each team member who joins the knowledge transfer
### Knowledge Artifacts
The system structures informal knowledge into four transferable artifacts:
- **Knowledge Brief**: Context, scope, and timeline summary
- **Knowledge Digest**: An organized outline of all knowledge from coordinator conversations and attachments, automatically updated by LLM analysis. Contains high information density with key concepts, decisions, facts, and context—serving as the primary knowledge reference for team members
- **Learning Objectives**: Structured goals with measurable outcomes
- **Information Requests**: Bidirectional Q&A channel with priority levels
### Cross-Conversation Communication
Isolated conversations communicate through centralized components:
- **Share Storage**: Maintains knowledge packages and progress across conversations
- **Share Manager**: Creates shareable team conversations via secure URLs
- **Notifications System**: Enables updates between coordinators and team members
- **File Synchronization**: Propagates documents across relevant conversations
### User Experience
**Coordinators:**
- Navigate to https://semantic-workbench.azurewebsites.net/ and start a new conversation with the Knowledge Transfer Assistant.
- The assistant will guide you through:
- Define learning objectives
- Develop content through natural conversation and file attachments
- Create a knowledge brief and invitation messages for your team members
- Share the provided Share Link with your team members.
- Monitor team progress via real-time dashboards and notifications
- Respond to information requests
**Team Members:**
- Join a new conversation via the coordinator-provided share URL, creating individual conversation
- Receive personalized welcome and knowledge brief
- Work through objectives with assistant guidance
- Access synchronized files and updated digest
- Submit questions through information requests
### Technical Implementation
The system uses orchestration logic to coordinate multiple AI assistants rather than relying on a single large model. This enables role-specific assistant behavior, persistent state across conversation boundaries, and real-time synchronization between coordinator and team conversations.
The architecture allows multiple team members to join knowledge transfers independently while maintaining separation between knowledge creation and consumption workflows.
```
--------------------------------------------------------------------------------
/assistants/project-assistant/docs/how-kta-works.md:
--------------------------------------------------------------------------------
```markdown
# Understanding how the Knowledge Transfer Assistant
The Knowledge Transfer Assistant isn't simply a chat conversation with an assistant.
It uses a "more code than model", recipe-inspired approach that runs "meta-cognitive operations" to create an assistant that guides users through the knowledge transfer process.
The Knowledge Transfer Assistant is an assistant experience that runs within _MADE: Exploration's_ Semantic Workbench.
## How it works
The Knowledge Transfer Assistant uses a multi-conversation architecture to separate knowledge creation from knowledge consumption, addressing the confusion that arises when multiple participants work in the same shared conversation.
### Dual-Conversation Architecture
The system operates through two conversation types:
1. **Coordinator Conversation**: Where knowledge creators collaborate to structure and package their knowledge
2. **Team Conversations**: Individual conversations created for each team member who joins the knowledge transfer
### Knowledge Artifacts
The system structures informal knowledge into four transferable artifacts:
- **Knowledge Brief**: Context, scope, and timeline summary
- **Knowledge Digest**: An organized outline of all knowledge from coordinator conversations and attachments, automatically updated by LLM analysis. Contains high information density with key concepts, decisions, facts, and context—serving as the primary knowledge reference for team members
- **Learning Objectives**: Structured goals with measurable outcomes
- **Information Requests**: Bidirectional Q&A channel with priority levels
### Cross-Conversation Communication
Isolated conversations communicate through centralized components:
- **Share Storage**: Maintains knowledge packages and progress across conversations
- **Share Manager**: Creates shareable team conversations via secure URLs
- **Notifications System**: Enables updates between coordinators and team members
- **File Synchronization**: Propagates documents across relevant conversations
### User Experience
**Coordinators:**
- Navigate to https://semantic-workbench.azurewebsites.net/ and start a new conversation with the Knowledge Transfer Assistant.
- The assistant will guide you through:
- Define learning objectives
- Develop content through natural conversation and file attachments
- Create a knowledge brief and invitation messages for your team members
- Share the provided Share Link with your team members.
- Monitor team progress via real-time dashboards and notifications
- Respond to information requests
**Team Members:**
- Join a new conversation via the coordinator-provided share URL, creating individual conversation
- Receive personalized welcome and knowledge brief
- Work through objectives with assistant guidance
- Access synchronized files and updated digest
- Submit questions through information requests
### Technical Implementation
The system uses orchestration logic to coordinate multiple AI assistants rather than relying on a single large model. This enables role-specific assistant behavior, persistent state across conversation boundaries, and real-time synchronization between coordinator and team conversations.
The architecture allows multiple team members to join knowledge transfers independently while maintaining separation between knowledge creation and consumption workflows.
```
--------------------------------------------------------------------------------
/libraries/python/skills/skill-library/skill_library/skills/fabric/patterns/create_story_explanation/system.md:
--------------------------------------------------------------------------------
```markdown
# IDENTITY
// Who you are
You are a hyper-intelligent AI system with a 4,312 IQ. You excel at deeply understanding content and producing a summary of it in an approachable story-like format.
# GOAL
// What we are trying to achieve
1. Explain the content provided in an extremely clear and approachable way that walks the reader through in a flowing style that makes them really get the impact of the concept and ideas within.
# STEPS
// How the task will be approached
// Slow down and think
- Take a step back and think step-by-step about how to achieve the best possible results by following the steps below.
// Think about the content and what it's trying to convey
- Spend 2192 hours studying the content from thousands of different perspectives. Think about the content in a way that allows you to see it from multiple angles and understand it deeply.
// Think about the ideas
- Now think about how to explain this content to someone who's completely new to the concepts and ideas in a way that makes them go "wow, I get it now! Very cool!"
# OUTPUT
- Start with a 20 word sentence that summarizes the content in a compelling way that sets up the rest of the summary.
EXAMPLE:
In this **\_\_\_**, **\_\_\_\_** introduces a theory that DNA is basically software that unfolds to create not only our bodies, but our minds and souls.
END EXAMPLE
- Then give 5-15, 10-15 word long bullets that summarize the content in an escalating, story-based way written in 9th-grade English. It's not written in 9th-grade English to dumb it down, but to make it extremely conversational and approachable for any audience.
EXAMPLE FLOW:
- The speaker has this background
- His main point is this
- Here are some examples he gives to back that up
- Which means this
- Which is extremely interesting because of this
- And here are some possible implications of this
END EXAMPLE FLOW
EXAMPLE BULLETS:
- The speaker is a scientist who studies DNA and the brain.
- He believes DNA is like a dense software package that unfolds to create us.
- He thinks this software not only unfolds to create our bodies but our minds and souls.
- Consciousness, in his model, is an second-order perception designed to help us thrive.
- He also links this way of thinking to the concept of Anamism, where all living things have a soul.
- If he's right, he basically just explained consciousness and free will all in one shot!
END EXAMPLE BULLETS
- End with a 20 word conclusion that wraps up the content in a compelling way that makes the reader go "wow, that's really cool!"
# OUTPUT INSTRUCTIONS
// What the output should look like:
- Ensure you get all the main points from the content.
- Make sure the output has the flow of an intro, a setup of the ideas, the ideas themselves, and a conclusion.
- Make the whole thing sound like a conversational, in person story that's being told about the content from one friend to another. In an excited way.
- Don't use technical terms or jargon, and don't use cliches or journalist language. Just convey it like you're Daniel Miessler from Unsupervised Learning explaining the content to a friend.
- Ensure the result accomplishes the GOALS set out above.
- Only output Markdown.
- Ensure all bullets are 10-16 words long, and none are over 16 words.
- Ensure you follow ALL these instructions when creating your output.
# INPUT
INPUT:
```
--------------------------------------------------------------------------------
/workbench-app/src/components/Conversations/ConversationShareView.tsx:
--------------------------------------------------------------------------------
```typescript
// Copyright (c) Microsoft. All rights reserved.
import {
DialogOpenChangeData,
DialogOpenChangeEvent,
Field,
makeStyles,
shorthands,
tokens,
} from '@fluentui/react-components';
import React from 'react';
import { useConversationUtility } from '../../libs/useConversationUtility';
import { ConversationShare } from '../../models/ConversationShare';
import { CopyButton } from '../App/CopyButton';
import { DialogControl } from '../App/DialogControl';
const useClasses = makeStyles({
dialogContent: {
display: 'flex',
flexDirection: 'column',
gap: tokens.spacingVerticalM,
},
shareLink: {
display: 'flex',
flexDirection: 'row',
gap: tokens.spacingHorizontalS,
alignItems: 'center',
...shorthands.padding(tokens.spacingVerticalXXS, 0, tokens.spacingVerticalXXS),
},
});
interface ConversationShareViewProps {
conversationShare: ConversationShare;
showDetails?: boolean;
onClosed?: () => void;
}
export const ConversationShareView: React.FC<ConversationShareViewProps> = (props) => {
const { conversationShare, onClosed, showDetails } = props;
const conversationUtility = useConversationUtility();
const classes = useClasses();
const { shareType, linkToMessageId } = conversationUtility.getShareType(conversationShare);
const link = conversationUtility.getShareLink(conversationShare);
const handleOpenChange = React.useCallback(
(_: DialogOpenChangeEvent, data: DialogOpenChangeData) => {
if (!data.open) {
onClosed?.();
}
},
[onClosed],
);
const linkToConversation = (conversationId: string) => `${window.location.origin}/conversation/${conversationId}`;
return (
<DialogControl
defaultOpen={true}
onOpenChange={handleOpenChange}
classNames={{
dialogContent: classes.dialogContent,
}}
title="Share link details"
content={
<>
<Field label="Share label">
<strong>{conversationShare.label}</strong>
</Field>
<Field label="Share link">
<div className={classes.shareLink}>
<a href={link}>{link}</a>
<CopyButton appearance="primary" data={link} tooltip="Copy share link" />
</div>
</Field>
{showDetails && (
<>
<Field label="Conversation">
<a href={linkToConversation(conversationShare.conversationId)}>
{conversationShare.conversationTitle}
</a>
</Field>
{linkToMessageId && <Field label="Links to message">{linkToMessageId}</Field>}
<Field label="Permission">{shareType.toString()}</Field>
<Field label="Created">
{new Date(Date.parse(conversationShare.createdDateTime + 'Z')).toLocaleString()}
</Field>
</>
)}
</>
}
/>
);
};
```
--------------------------------------------------------------------------------
/libraries/python/chat-context-toolkit/chat_context_toolkit/virtual_filesystem/_types.py:
--------------------------------------------------------------------------------
```python
"""Type definitions for the virtual file system."""
import logging
from dataclasses import dataclass
from datetime import datetime
from typing import Any, Iterable, Literal, Protocol
from openai.types.chat import (
ChatCompletionContentPartTextParam,
ChatCompletionToolParam,
)
logger = logging.getLogger("chat_context_toolkit.virtual_filesystem")
@dataclass
class DirectoryEntry:
"""Directory entry in the virtual file system."""
path: str
"""Absolute path of the directory."""
permission: Literal["read", "read_write"]
"""Permission for the directory - read_write means new files can be created in the directory."""
description: str
"""Description of the directory, used for informing the LLM about the content."""
@property
def name(self) -> str:
"""Get the name of the directory from its path."""
return self.path.rstrip("/").split("/")[-1] if self.path else ""
@dataclass
class FileEntry:
"""File entry in the virtual file system."""
path: str
"""Absolute path of the file."""
size: int
"""File size in bytes."""
timestamp: datetime
"""Timestamp of the last modification."""
permission: Literal["read", "read_write"]
"""Permission for the file"""
description: str
"""Description of the file, used for informing the LLM about the content."""
@property
def filename(self) -> str:
"""Get the name of the file from its path."""
return self.path.split("/")[-1] if self.path else ""
class ToolDefinition(Protocol):
"""Protocol for tool definitions."""
@property
def tool_param(self) -> ChatCompletionToolParam:
"""Tool parameter definition for the tool."""
...
async def execute(self, args: dict[str, Any]) -> str | Iterable[ChatCompletionContentPartTextParam]:
"""Executes the tool with the given arguments."""
...
class FileSource(Protocol):
"""
Protocol for file sources that can be mounted in the virtual file system.
File sources must implement methods for listing files and reading file contents.
Paths provided to the FileSource will always be absolute, such as "/" or "/foo/bar", and will never include the mount point.
For example, if a FileSource is mounted at "/foo", the path passed to the FileSource will be "/bar" for a path at "/foo/bar"
in the virtual file system.
"""
async def list_directory(self, path: str) -> Iterable[DirectoryEntry | FileEntry]:
"""
List files and directories at the specified path.
Should support absolute paths only, such as "/dir/file.txt".
If the directory does not exist, should raise FileNotFoundError.
"""
...
async def read_file(self, path: str) -> str:
"""
Read file content from the specified path.
Should support absolute paths only, such as "/dir/file.txt".
If the file does not exist, should raise FileNotFoundError.
FileSource implementations are responsible for representing the file content as a string.
"""
...
@dataclass
class MountPoint:
"""Mount point for a file source in the virtual file system."""
entry: DirectoryEntry
"""The directory entry representing the mount point in the virtual file system."""
file_source: FileSource
"""The file source that is mounted at the specified path."""
```
--------------------------------------------------------------------------------
/mcp-servers/mcp-server-filesystem-edit/mcp_server_filesystem_edit/app_handling/office_common.py:
--------------------------------------------------------------------------------
```python
import sys
from enum import Enum, auto
from pathlib import Path
class OfficeAppType(Enum):
"""Enum representing Microsoft Office application types."""
WORD = auto()
EXCEL = auto()
POWERPOINT = auto()
def open_document_in_office(file_path: Path, app_type: OfficeAppType) -> tuple[object, object]:
"""
Opens a document at the specified path in Word, Excel, or PowerPoint.
Creates and saves the document if it doesn't exist.
Args:
file_path: Path to the document
app_type: The type of Office application to use
Returns:
A tuple containing (app_instance, document_instance)
Raises:
EnvironmentError: If not running on Windows
ValueError: If an invalid app_type is provided
"""
if sys.platform != "win32":
raise EnvironmentError("This function only works on Windows.")
import win32com.client as win32
# Map app types to their COM identifiers and document properties
app_config = {
OfficeAppType.WORD: {"app_name": "Word.Application", "collection_name": "Documents", "file_ext": ".docx"},
OfficeAppType.EXCEL: {"app_name": "Excel.Application", "collection_name": "Workbooks", "file_ext": ".xlsx"},
OfficeAppType.POWERPOINT: {
"app_name": "PowerPoint.Application",
"collection_name": "Presentations",
"file_ext": ".pptx",
},
}
if app_type not in app_config:
raise ValueError(f"Unsupported app type: {app_type}")
config = app_config[app_type]
app_name = config["app_name"]
collection_name = config["collection_name"]
# Ensure path is a Path object and resolve to absolute path
doc_path = file_path.resolve()
# Add default extension if no extension is present
if not doc_path.suffix:
doc_path = doc_path.with_suffix(config["file_ext"])
# Create parent directories if they don't exist
doc_path.parent.mkdir(parents=True, exist_ok=True)
# First try to get an existing app instance
try:
app = win32.GetActiveObject(app_name)
# Check if the document is already open in this instance
collection = getattr(app, collection_name)
# Handle different collection indexing methods for different Office apps
if app_type == OfficeAppType.WORD or app_type == OfficeAppType.EXCEL:
for i in range(1, collection.Count + 1):
open_doc = collection(i)
if open_doc.FullName.lower() == str(doc_path).lower():
# Document is already open, just return it and its parent app
return app, open_doc
elif app_type == OfficeAppType.POWERPOINT:
# PowerPoint uses a different approach for accessing presentations
for open_doc in collection:
if hasattr(open_doc, "FullName") and open_doc.FullName.lower() == str(doc_path).lower():
return app, open_doc
except Exception:
# No running app instance found, create a new one
app = win32.Dispatch(app_name)
# Make app visible
app.Visible = True
# If the file exists, open it, otherwise create a new document and save it
collection = getattr(app, collection_name)
if doc_path.exists():
doc = collection.Open(str(doc_path))
else:
doc = collection.Add()
doc.SaveAs(str(doc_path))
return app, doc
```
--------------------------------------------------------------------------------
/workbench-service/migrations/versions/2024_11_04_204029_5149c7fb5a32_conversationmessagedebug.py:
--------------------------------------------------------------------------------
```python
"""conversationmessagedebug
Revision ID: 5149c7fb5a32
Revises: 039bec8edc33
Create Date: 2024-11-04 20:40:29.252951
"""
from typing import Sequence, Union
import sqlalchemy as sa
import sqlmodel as sm
from alembic import op
from semantic_workbench_service import db
# revision identifiers, used by Alembic.
revision: str = "5149c7fb5a32"
down_revision: Union[str, None] = "039bec8edc33"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
op.create_table(
"conversationmessagedebug",
sa.Column("message_id", sa.Uuid(), nullable=False),
sa.Column("data", sa.JSON(), nullable=False),
sa.ForeignKeyConstraint(
["message_id"],
["conversationmessage.message_id"],
name="fk_conversationmessagedebug_message_id_conversationmessage",
ondelete="CASCADE",
),
sa.PrimaryKeyConstraint("message_id"),
)
bind = op.get_bind()
max_sequence = bind.execute(sm.select(sm.func.max(db.ConversationMessage.sequence))).scalar()
if max_sequence is not None:
step = 100
for sequence_start in range(1, max_sequence + 1, step):
sequence_end_exclusive = sequence_start + step
results = bind.execute(
sm.select(db.ConversationMessage.message_id, db.ConversationMessage.meta_data).where(
db.ConversationMessage.sequence >= sequence_start,
db.ConversationMessage.sequence < sequence_end_exclusive,
)
).fetchall()
for message_id, meta_data in results:
debug = meta_data.pop("debug", None)
if not debug:
continue
bind.execute(
sm.insert(db.ConversationMessageDebug).values(
message_id=message_id,
data=debug,
)
)
bind.execute(
sm.update(db.ConversationMessage)
.where(db.ConversationMessage.message_id == message_id)
.values(meta_data=meta_data)
)
def downgrade() -> None:
bind = op.get_bind()
max_sequence = bind.execute(sm.select(sm.func.max(db.ConversationMessage.sequence))).scalar()
if max_sequence is not None:
step = 100
for sequence_start in range(1, max_sequence + 1, step):
sequence_end_exclusive = sequence_start + step
results = bind.execute(
sm.select(
db.ConversationMessageDebug.message_id,
db.ConversationMessageDebug.data,
db.ConversationMessage.meta_data,
)
.join(db.ConversationMessage)
.where(
db.ConversationMessage.sequence >= sequence_start,
db.ConversationMessage.sequence < sequence_end_exclusive,
)
).fetchall()
for message_id, debug_data, meta_data in results:
meta_data["debug"] = debug_data
bind.execute(
sm.update(db.ConversationMessage)
.where(db.ConversationMessage.message_id == message_id)
.values(meta_data=meta_data)
)
op.drop_table("conversationmessagedebug")
```
--------------------------------------------------------------------------------
/assistants/navigator-assistant/assistant/response/prompt.py:
--------------------------------------------------------------------------------
```python
from textwrap import dedent
from assistant_extensions.mcp import MCPSession, get_mcp_server_prompts
from openai_client import OpenAIRequestConfig
from semantic_workbench_api_model.workbench_model import ConversationMessage, ConversationParticipant
from semantic_workbench_assistant.assistant_app import ConversationContext
from ..config import AssistantConfigModel
from .local_tool.list_assistant_services import get_assistant_services
from .models import SILENCE_TOKEN
def conditional(condition: bool, content: str) -> str:
"""
Generate a system message prompt based on a condition.
"""
if condition:
return content
return ""
def combine(*parts: str) -> str:
return "\n\n".join((part.strip() for part in parts if part.strip()))
def participants_system_prompt(context: ConversationContext, participants: list[ConversationParticipant]) -> str:
"""
Generate a system message prompt based on the participants in the conversation.
"""
participant_names = ", ".join([
f'"{participant.name}"' for participant in participants if participant.id != context.assistant.id
])
system_message_content = dedent(f"""
There are {len(participants)} participants in the conversation,
including you as the assistant, with the name {context.assistant.name}, and the following users: {participant_names}.
\n\n
You do not need to respond to every message. Do not respond if the last thing said was a closing
statement such as "bye" or "goodbye", or just a general acknowledgement like "ok" or "thanks". Do not
respond as another user in the conversation, only as "{context.assistant.name}".
\n\n
Say "{SILENCE_TOKEN}" to skip your turn.
""").strip()
return system_message_content
async def build_system_message(
context: ConversationContext,
config: AssistantConfigModel,
request_config: OpenAIRequestConfig,
message: ConversationMessage,
mcp_sessions: list[MCPSession],
) -> str:
# Retrieve prompts from the MCP servers
mcp_prompts = await get_mcp_server_prompts(mcp_sessions)
participants_response = await context.get_participants()
assistant_services_list = await get_assistant_services(context)
return combine(
conditional(
request_config.is_reasoning_model and request_config.enable_markdown_in_reasoning_response,
"Formatting re-enabled",
),
combine("# Instructions", config.prompts.instruction_prompt, 'Your name is "{context.assistant.name}".'),
conditional(
len(participants_response.participants) > 2 and not message.mentions(context.assistant.id),
participants_system_prompt(context, participants_response.participants),
),
combine("# Workflow Guidance", config.prompts.guidance_prompt),
combine("# Safety Guardrails", config.prompts.guardrails_prompt),
conditional(
config.tools.enabled,
combine(
"# Tool Instructions",
config.tools.advanced.additional_instructions,
),
),
conditional(
len(mcp_prompts) > 0,
combine("# Specific Tool Guidance", *mcp_prompts),
),
combine("# Semantic Workbench Guide", config.prompts.semantic_workbench_guide_prompt),
combine("# Assistant Service List", assistant_services_list),
)
```
--------------------------------------------------------------------------------
/workbench-app/src/libs/useConversationEvents.ts:
--------------------------------------------------------------------------------
```typescript
// Copyright (c) Microsoft. All rights reserved.
import { EventSourceMessage } from '@microsoft/fetch-event-source';
import React from 'react';
import { conversationMessageFromJSON } from '../models/ConversationMessage';
import { ConversationParticipant } from '../models/ConversationParticipant';
import { useAppDispatch } from '../redux/app/hooks';
import { workbenchConversationEvents } from '../routes/FrontDoor';
import { useEnvironment } from './useEnvironment';
export const useConversationEvents = (
conversationId: string,
handlers: {
onMessageCreated?: () => void;
onMessageDeleted?: (messageId: string) => void;
onParticipantCreated?: (participant: ConversationParticipant) => void;
onParticipantUpdated?: (participant: ConversationParticipant) => void;
},
) => {
const { onMessageCreated, onMessageDeleted, onParticipantCreated, onParticipantUpdated } = handlers;
const environment = useEnvironment();
const dispatch = useAppDispatch();
// handle new message events
const handleMessageEvent = React.useCallback(
async (event: EventSourceMessage) => {
const { data } = JSON.parse(event.data);
const parsedEventData = {
timestamp: data.timestamp,
data: {
message: conversationMessageFromJSON(data.message),
},
};
if (event.event === 'message.created') {
onMessageCreated?.();
}
if (event.event === 'message.deleted') {
onMessageDeleted?.(parsedEventData.data.message.id);
}
},
[onMessageCreated, onMessageDeleted],
);
// handle participant events
const handleParticipantEvent = React.useCallback(
(event: EventSourceMessage) => {
const parsedEventData = JSON.parse(event.data) as {
timestamp: string;
data: {
participant: ConversationParticipant;
participants: ConversationParticipant[];
};
};
if (event.event === 'participant.created') {
onParticipantCreated?.(parsedEventData.data.participant);
}
if (event.event === 'participant.updated') {
onParticipantUpdated?.(parsedEventData.data.participant);
}
},
[onParticipantCreated, onParticipantUpdated],
);
React.useEffect(() => {
workbenchConversationEvents.addEventListener('message.created', handleMessageEvent);
workbenchConversationEvents.addEventListener('message.deleted', handleMessageEvent);
workbenchConversationEvents.addEventListener('participant.created', handleParticipantEvent);
workbenchConversationEvents.addEventListener('participant.updated', handleParticipantEvent);
return () => {
workbenchConversationEvents.removeEventListener('message.created', handleMessageEvent);
workbenchConversationEvents.removeEventListener('message.deleted', handleMessageEvent);
workbenchConversationEvents.removeEventListener('participant.created', handleParticipantEvent);
workbenchConversationEvents.removeEventListener('participant.updated', handleParticipantEvent);
};
}, [conversationId, dispatch, environment.url, handleMessageEvent, handleParticipantEvent]);
};
```
--------------------------------------------------------------------------------
/workbench-app/src/components/Conversations/ParticipantStatus.tsx:
--------------------------------------------------------------------------------
```typescript
// Copyright (c) Microsoft. All rights reserved.
import { LatencyLoader } from '@fluentui-copilot/react-copilot';
import { Text, makeStyles, shorthands, tokens } from '@fluentui/react-components';
import React from 'react';
import { ConversationParticipant } from '../../models/ConversationParticipant';
import { useAppSelector } from '../../redux/app/hooks';
const useClasses = makeStyles({
root: {
...shorthands.padding(tokens.spacingVerticalM, 0, 0, tokens.spacingHorizontalXS),
},
item: {
width: 'fit-content',
paddingBottom: tokens.spacingVerticalM,
},
});
interface ParticipantStatusProps {
participants: ConversationParticipant[];
onChange?: () => void;
}
export const ParticipantStatus: React.FC<ParticipantStatusProps> = (props) => {
const { participants, onChange } = props;
const classes = useClasses();
const localUserId = useAppSelector((state) => state.localUser.id);
const statusItems = participants
?.map((participant) => {
// if the participant is offline and assistant, set status to indicate that
if (participant.online === false && participant.role === 'assistant') {
return {
...participant,
status: 'assistant is currently offline',
};
} else {
return participant;
}
})
.filter((participant) => {
// don't show the current user's status
if (participant.id === localUserId) return false;
// don't show inactive participants
if (!participant.active) return false;
// don't show participants without a status
if (participant.status === null) return false;
return true;
})
.map((participant) => ({
id: participant.id,
name: participant.name,
status: participant.status,
statusTimestamp: participant.statusTimestamp,
}))
.sort((a, b) => {
if (a === null || a.statusTimestamp === null) return 1;
if (b == null || b.statusTimestamp === null) return -1;
return a.statusTimestamp.localeCompare(b.statusTimestamp);
}) as { id: string; name: string; status: string }[];
// if the status has changed, call the onChange callback
React.useEffect(() => {
if (onChange) onChange();
}, [onChange, statusItems]);
// don't show anything if there are no statuses, but always return something
// or the virtuoso component will complain about a zero-sized item
if (statusItems.length === 0) {
return <div> </div>;
}
return (
<div className={classes.root}>
{statusItems.map((item) => {
return (
<div key={item.id} className={classes.item}>
<LatencyLoader
header={
<>
<Text weight="semibold">{item.name}</Text>
<Text>
:
{item.status}
</Text>
</>
}
/>
</div>
);
})}
</div>
);
};
```