This is page 23 of 145. Use http://codebase.md/microsoft/semanticworkbench?lines=true&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
--------------------------------------------------------------------------------
/libraries/python/assistant-extensions/assistant_extensions/document_editor/_extension.py:
--------------------------------------------------------------------------------
```python
1 | from contextlib import asynccontextmanager
2 | from typing import AsyncGenerator
3 |
4 | from assistant_drive import Drive, DriveConfig
5 | from semantic_workbench_assistant.assistant_app import (
6 | AssistantAppProtocol,
7 | ConversationContext,
8 | storage_directory_for_context,
9 | )
10 |
11 | from ..mcp._assistant_file_resource_handler import AssistantFileResourceHandler
12 | from ._inspector import DocumentInspectors, lock_document_edits
13 | from ._model import DocumentEditorConfigProvider
14 |
15 |
16 | class DocumentEditorExtension:
17 | """
18 | Document Editor Extension for an Assistant. This extension provides functionality in support of MCP servers
19 | that can edit documents. It provides a client-resource handler, backed by a Drive, that the MCP server can
20 | read and write document files to. Additionally, it provides inspectors for viewing the document file list,
21 | viewing the documents, as well as editing the documents.
22 | """
23 |
24 | def __init__(
25 | self,
26 | app: AssistantAppProtocol,
27 | config_provider: DocumentEditorConfigProvider,
28 | storage_directory: str = "documents",
29 | ) -> None:
30 | self._app = app
31 | self._storage_directory = storage_directory
32 | self._inspectors = DocumentInspectors(
33 | app=app,
34 | config_provider=config_provider,
35 | drive_provider=self._drive_for,
36 | )
37 |
38 | def _drive_for(self, ctx: ConversationContext) -> Drive:
39 | root = storage_directory_for_context(ctx) / self._storage_directory
40 | drive = Drive(DriveConfig(root=root))
41 | return drive
42 |
43 | def client_resource_handler_for(self, ctx: ConversationContext) -> AssistantFileResourceHandler:
44 | return AssistantFileResourceHandler(
45 | context=ctx,
46 | drive=self._drive_for(ctx),
47 | onwrite=self._inspectors.on_external_write,
48 | )
49 |
50 | @asynccontextmanager
51 | async def lock_document_edits(self, ctx: ConversationContext) -> AsyncGenerator[None, None]:
52 | """
53 | Lock the document for editing and return a context manager that will unlock the document when exited.
54 | """
55 | async with lock_document_edits(app=self._app, context=ctx) as lock:
56 | yield lock
57 |
```
--------------------------------------------------------------------------------
/.github/workflows/assistants-knowledge-transfer-assistant.yml:
--------------------------------------------------------------------------------
```yaml
1 | name: knowledge-transfer-assistant continuous integration
2 |
3 | permissions:
4 | contents: read
5 | pull-requests: write
6 |
7 | on:
8 | pull_request:
9 | branches: ["main"]
10 | paths:
11 | - "assistants/knowledge-transfer-assistant/**"
12 | - "libraries/python/**"
13 | - "tools/docker/**"
14 | - ".github/workflows/assistants-knowledge-transfer-assistant.yml"
15 |
16 | push:
17 | branches: ["main"]
18 | paths:
19 | - "assistants/knowledge-transfer-assistant/**"
20 | - "libraries/python/**"
21 | - "tools/docker/**"
22 | - ".github/workflows/assistants-knowledge-transfer-assistant.yml"
23 |
24 | workflow_dispatch:
25 |
26 | defaults:
27 | run:
28 | working-directory: assistants/knowledge-transfer-assistant
29 |
30 | jobs:
31 | test:
32 | runs-on: ubuntu-latest
33 | steps:
34 | - uses: actions/checkout@v4
35 |
36 | - name: Install uv
37 | uses: astral-sh/setup-uv@v3
38 |
39 | - name: Set up Python 3.11
40 | run: uv python install 3.11
41 |
42 | - name: test
43 | run: |
44 | make test
45 |
46 | build:
47 | runs-on: ubuntu-latest
48 | steps:
49 | - uses: actions/checkout@v4
50 |
51 | - name: docker-build
52 | run: |
53 | make docker-build
54 |
55 | deploy:
56 | runs-on: ubuntu-latest
57 | environment: production
58 | permissions:
59 | id-token: write # for OIDC login
60 | contents: read
61 | concurrency:
62 | group: ${{ github.workflow }}-${{ github.ref }}
63 | needs: [build, test]
64 | if: ${{ (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main' && vars.DEPLOYMENT_ENABLED == 'true' }}
65 | env:
66 | DOCKER_IMAGE_TAG: ${{ github.sha }}
67 | DOCKER_REGISTRY_NAME: ${{ secrets.AZURE_CONTAINER_REGISTRY_NAME }}
68 | AZURE_WEBSITE_RESOURCE_GROUP: ${{ secrets.AZURE_WEBSITE_RESOURCE_GROUP }}
69 | AZURE_WEBSITE_SUBSCRIPTION: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
70 |
71 | steps:
72 | - uses: actions/checkout@v4
73 |
74 | - uses: azure/login@v2
75 | with:
76 | client-id: ${{ secrets.AZURE_CLIENT_ID }}
77 | tenant-id: ${{ secrets.AZURE_TENANT_ID }}
78 | subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
79 |
80 | - name: docker-push
81 | run: |
82 | make docker-push
83 |
84 | - name: docker-deploy
85 | run: |
86 | make docker-deploy
87 |
```
--------------------------------------------------------------------------------
/.github/workflows/assistants-guided-conversation-assistant.yml:
--------------------------------------------------------------------------------
```yaml
1 | name: guided-conversation-assistant continuous integration
2 |
3 | permissions:
4 | contents: read
5 | pull-requests: write
6 |
7 | on:
8 | pull_request:
9 | branches: ["main"]
10 | paths:
11 | - "assistants/guided-conversation-assistant/**"
12 | - "libraries/python/**"
13 | - "tools/docker/**"
14 | - ".github/workflows/assistants-guided-conversation-assistant.yml"
15 |
16 | push:
17 | branches: ["main"]
18 | paths:
19 | - "assistants/guided-conversation-assistant/**"
20 | - "libraries/python/**"
21 | - "tools/docker/**"
22 | - ".github/workflows/assistants-guided-conversation-assistant.yml"
23 |
24 | workflow_dispatch:
25 |
26 | defaults:
27 | run:
28 | working-directory: assistants/guided-conversation-assistant
29 |
30 | jobs:
31 | test:
32 | runs-on: ubuntu-latest
33 | steps:
34 | - uses: actions/checkout@v4
35 |
36 | - name: Install uv
37 | uses: astral-sh/setup-uv@v3
38 |
39 | - name: Set up Python 3.11
40 | run: uv python install 3.11
41 |
42 | - name: test
43 | run: |
44 | make test
45 |
46 | build:
47 | runs-on: ubuntu-latest
48 | steps:
49 | - uses: actions/checkout@v4
50 |
51 | - name: docker-build
52 | run: |
53 | make docker-build
54 |
55 | deploy:
56 | runs-on: ubuntu-latest
57 | environment: production
58 | permissions:
59 | id-token: write # for OIDC login
60 | contents: read
61 | concurrency:
62 | group: ${{ github.workflow }}-${{ github.ref }}
63 | needs: [build, test]
64 | if: ${{ (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main' && vars.DEPLOYMENT_ENABLED == 'true' }}
65 | env:
66 | DOCKER_IMAGE_TAG: ${{ github.sha }}
67 | DOCKER_REGISTRY_NAME: ${{ secrets.AZURE_CONTAINER_REGISTRY_NAME }}
68 | AZURE_WEBSITE_RESOURCE_GROUP: ${{ secrets.AZURE_WEBSITE_RESOURCE_GROUP }}
69 | AZURE_WEBSITE_SUBSCRIPTION: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
70 |
71 | steps:
72 | - uses: actions/checkout@v4
73 |
74 | - uses: azure/login@v2
75 | with:
76 | client-id: ${{ secrets.AZURE_CLIENT_ID }}
77 | tenant-id: ${{ secrets.AZURE_TENANT_ID }}
78 | subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
79 |
80 | - name: docker-push
81 | run: |
82 | make docker-push
83 |
84 | - name: docker-deploy
85 | run: |
86 | make docker-deploy
87 |
```
--------------------------------------------------------------------------------
/mcp-servers/mcp-server-bing-search/mcp_server_bing_search/types.py:
--------------------------------------------------------------------------------
```python
1 | # Copyright (c) Microsoft. All rights reserved.
2 |
3 | import hashlib
4 | import json
5 | import threading
6 |
7 | from pydantic import BaseModel, Field, model_validator
8 |
9 | from mcp_server_bing_search import settings
10 |
11 | # Module-level lock for thread safety
12 | _url_cache_lock = threading.Lock()
13 |
14 |
15 | class Link(BaseModel):
16 | url: str
17 | unique_id: str = ""
18 |
19 | @model_validator(mode="before")
20 | @classmethod
21 | def set_unique_id(cls, data: dict) -> dict:
22 | """Automatically hash the URL to create unique_id if not provided."""
23 | if isinstance(data, dict):
24 | if "url" in data and (not data.get("unique_id")):
25 | data["unique_id"] = hash_and_cache_url(data["url"])
26 | return data
27 |
28 |
29 | class WebResult(BaseModel):
30 | url: str
31 | title: str
32 | content: str
33 | links: list[Link] = Field(default_factory=list, description="List of ids that uniquely identify the links")
34 |
35 |
36 | class SearchResult(BaseModel):
37 | display_url: str
38 | url: str
39 | name: str
40 | snippet: str
41 |
42 |
43 | def hash_and_cache_url(url: str) -> str:
44 | """
45 | Creates a hash of the given URL and stores that in a lookup file for later.
46 | Uses a threading lock to ensure thread safety.
47 |
48 | Args:
49 | url: The URL to hash
50 |
51 | Returns:
52 | The first 12 characters of the URL's SHA-256 hash in hexadecimal
53 | """
54 | cache_file = settings.url_cache_file
55 |
56 | # Create a SHA-256 hash of the URL
57 | url_hash = hashlib.sha256(url.encode("utf-8")).hexdigest()[:12]
58 |
59 | # Ensure the cache directory exists
60 | cache_file.parent.mkdir(parents=True, exist_ok=True)
61 |
62 | with _url_cache_lock:
63 | # Load existing cache or initialize empty dict
64 | cache = {}
65 | if cache_file.exists():
66 | try:
67 | with cache_file.open("r", encoding="utf-8") as f:
68 | cache = json.load(f)
69 | except json.JSONDecodeError:
70 | # If the file exists but is corrupted, start with empty cache
71 | cache = {}
72 |
73 | # Add the URL to the cache
74 | cache[url_hash] = url
75 |
76 | # Save the updated cache
77 | with cache_file.open("w", encoding="utf-8") as f:
78 | json.dump(cache, f, ensure_ascii=False, indent=2)
79 |
80 | return url_hash
81 |
```
--------------------------------------------------------------------------------
/mcp-servers/mcp-server-filesystem-edit/mcp_server_filesystem_edit/tools/helpers.py:
--------------------------------------------------------------------------------
```python
1 | # Copyright (c) Microsoft. All rights reserved.
2 |
3 | from collections.abc import Collection
4 | from typing import AbstractSet, Literal
5 |
6 | import tiktoken
7 | import tiktoken_ext # Importing explicitly to get around pyinstaller issue
8 | from mcp_extensions.llm.llm_types import MessageT
9 | from tiktoken_ext import openai_public # Importing explicitly to get around pyinstaller issue
10 |
11 |
12 | def format_chat_history(chat_history: list[MessageT]) -> str:
13 | formatted_chat_history = ""
14 | for message in chat_history:
15 | formatted_chat_history += f"[{message.role.value}]: {message.content}\n"
16 | return formatted_chat_history.strip()
17 |
18 |
19 | class TokenizerOpenAI:
20 | def __init__(
21 | self,
22 | model: str,
23 | allowed_special: Literal["all"] | AbstractSet[str] | None = None,
24 | disallowed_special: Literal["all"] | Collection[str] | None = None,
25 | ):
26 | self.model = model
27 | self.allowed_special = allowed_special
28 | self.disallowed_special = disallowed_special
29 |
30 | self.init_tokenizer(model, allowed_special, disallowed_special)
31 |
32 | # Hack to prevent imports from getting auto-deleted
33 | tiktoken_ext # type: ignore
34 | openai_public # type: ignore
35 |
36 | def init_tokenizer(
37 | self,
38 | model: str,
39 | allowed_special: Literal["all"] | AbstractSet[str] | None = None,
40 | disallowed_special: Literal["all"] | Collection[str] | None = None,
41 | ) -> None:
42 | try:
43 | self.encoding = tiktoken.encoding_for_model(model)
44 | except KeyError:
45 | default_encoding = "o200k_base"
46 | self.encoding = tiktoken.get_encoding(default_encoding)
47 |
48 | # Set defaults if not provided
49 | if not allowed_special:
50 | self.allowed_special = set()
51 | if not disallowed_special:
52 | self.disallowed_special = ()
53 |
54 | def num_tokens_in_str(self, text: str) -> int:
55 | return len(
56 | self.encoding.encode(
57 | text,
58 | allowed_special=self.allowed_special if self.allowed_special is not None else set(), # type: ignore
59 | disallowed_special=self.disallowed_special if self.disallowed_special is not None else (),
60 | )
61 | )
62 |
```
--------------------------------------------------------------------------------
/assistants/project-assistant/assistant/domain/knowledge_digest_manager.py:
--------------------------------------------------------------------------------
```python
1 | from datetime import UTC, datetime
2 |
3 | from semantic_workbench_assistant.assistant_app import ConversationContext
4 |
5 | from assistant.data import InspectorTab, KnowledgeDigest, LogEntryType
6 | from assistant.notifications import Notifications
7 | from assistant.storage import ShareStorage
8 | from assistant.utils import get_current_user_id
9 |
10 | from .share_manager import ShareManager
11 |
12 |
13 | class KnowledgeDigestManager:
14 | """Manages knowledge digest operations."""
15 |
16 | @staticmethod
17 | async def get_knowledge_digest(
18 | context: ConversationContext,
19 | ) -> KnowledgeDigest | None:
20 | share_id = await ShareManager.get_share_id(context)
21 | if not share_id:
22 | return None
23 | return ShareStorage.read_knowledge_digest(share_id)
24 |
25 | @staticmethod
26 | async def update_knowledge_digest(
27 | context: ConversationContext,
28 | content: str,
29 | is_auto_generated: bool = True,
30 | ) -> None:
31 | share_id = await ShareManager.get_share_id(context)
32 | current_user_id = await get_current_user_id(context)
33 |
34 | digest = ShareStorage.read_knowledge_digest(share_id)
35 | is_new = False
36 |
37 | if not digest:
38 | digest = KnowledgeDigest(
39 | created_by=current_user_id,
40 | updated_by=current_user_id,
41 | conversation_id=str(context.id),
42 | content="",
43 | )
44 | is_new = True
45 |
46 | digest.content = content
47 | digest.is_auto_generated = is_auto_generated
48 | digest.updated_at = datetime.now(UTC)
49 | digest.updated_by = current_user_id
50 | digest.version += 1
51 | ShareStorage.write_knowledge_digest(share_id, digest)
52 |
53 | # Log the update
54 | event_type = LogEntryType.KNOWLEDGE_DIGEST_UPDATE
55 | update_type = "auto-generated" if is_auto_generated else "manual"
56 | message = f"{'Created' if is_new else 'Updated'} knowledge digest ({update_type})"
57 |
58 | await ShareManager.log_share_event(
59 | context=context,
60 | entry_type=event_type.value,
61 | message=message,
62 | )
63 |
64 | await Notifications.notify_all_state_update(
65 | context,
66 | [InspectorTab.BRIEF],
67 | )
68 |
69 | return
70 |
```
--------------------------------------------------------------------------------
/examples/dotnet/dotnet-03-simple-chatbot/ConnectorExtensions.cs:
--------------------------------------------------------------------------------
```csharp
1 | // Copyright (c) Microsoft. All rights reserved.
2 |
3 | using System.Text;
4 | using Microsoft.SemanticKernel.ChatCompletion;
5 | using Microsoft.SemanticWorkbench.Connector;
6 |
7 | namespace AgentExample;
8 |
9 | public static class ConnectorExtensions
10 | {
11 | public static string GetParticipantName(this Conversation conversation, string id)
12 | {
13 | if (conversation.Participants.TryGetValue(id, out Participant? participant))
14 | {
15 | return participant.Name;
16 | }
17 |
18 | return "Unknown";
19 | }
20 |
21 | public static ChatHistory ToSemanticKernelChatHistory(
22 | this Conversation conversation,
23 | string assistantId,
24 | string systemPrompt)
25 | {
26 | var result = new ChatHistory(systemPrompt);
27 |
28 | foreach (Message msg in conversation.Messages)
29 | {
30 | if (msg.Sender.Id == assistantId)
31 | {
32 | result.AddAssistantMessage(msg.Content!);
33 | }
34 | else
35 | {
36 | result.AddUserMessage(
37 | $"[{conversation.GetParticipantName(msg.Sender.Id)}] {msg.Content}");
38 | }
39 | }
40 |
41 | return result;
42 | }
43 |
44 | public static string ToHtmlString(
45 | this Conversation conversation,
46 | string assistantId)
47 | {
48 | var result = new StringBuilder();
49 | result.AppendLine("<style>");
50 | result.AppendLine("DIV.conversationHistory { padding: 0 20px 60px 20px; }");
51 | result.AppendLine("DIV.conversationHistory P { margin: 0 0 8px 0; }");
52 | result.AppendLine("</style>");
53 | result.AppendLine("<div class='conversationHistory'>");
54 |
55 | foreach (var msg in conversation.Messages)
56 | {
57 | result.AppendLine("<p>");
58 | if (msg.Sender.Id == assistantId)
59 | {
60 | result.AppendLine("<b>Assistant</b><br/>");
61 | }
62 | else
63 | {
64 | result
65 | .Append("<b>")
66 | .Append(conversation.GetParticipantName(msg.Sender.Id))
67 | .AppendLine("</b><br/>");
68 | }
69 |
70 | result.AppendLine(msg.Content).AppendLine("</p>");
71 | }
72 |
73 | result.Append("</div>");
74 |
75 | return result.ToString();
76 | }
77 | }
78 |
```
--------------------------------------------------------------------------------
/libraries/python/assistant-extensions/assistant_extensions/attachments/_convert.py:
--------------------------------------------------------------------------------
```python
1 | import asyncio
2 | import base64
3 | import io
4 | import logging
5 | import pathlib
6 |
7 | import docx2txt
8 | import pdfplumber
9 |
10 | logger = logging.getLogger(__name__)
11 |
12 |
13 | async def bytes_to_str(file_bytes: bytes, filename: str) -> str:
14 | """
15 | Convert the content of the file to a string.
16 | """
17 | filename_extension = pathlib.Path(filename).suffix.lower().strip(".")
18 |
19 | match filename_extension:
20 | # if the file has .docx extension, convert it to text
21 | case "docx":
22 | return await _docx_bytes_to_str(file_bytes)
23 |
24 | # if the file has .pdf extension, convert it to text
25 | case "pdf":
26 | return await _pdf_bytes_to_str(file_bytes)
27 |
28 | # if the file has an image extension, convert it to a data URI
29 | case _ if filename_extension in ["png", "jpg", "jpeg", "gif", "bmp", "tiff", "tif"]:
30 | return _image_bytes_to_str(file_bytes, filename_extension)
31 |
32 | # otherwise, try to convert the file to text
33 | case _:
34 | return file_bytes.decode("utf-8")
35 |
36 |
37 | async def _docx_bytes_to_str(file_bytes: bytes) -> str:
38 | """
39 | Convert a DOCX file to text.
40 | """
41 | with io.BytesIO(file_bytes) as temp:
42 | text = await asyncio.to_thread(docx2txt.process, docx=temp)
43 | return text
44 |
45 |
46 | async def _pdf_bytes_to_str(file_bytes: bytes, max_pages: int = 10) -> str:
47 | """
48 | Convert a PDF file to text.
49 |
50 | Args:
51 | file_bytes: The raw content of the PDF file.
52 | max_pages: The maximum number of pages to read from the PDF file.
53 | """
54 |
55 | def _read_pages() -> str:
56 | pages = []
57 | with io.BytesIO(file_bytes) as temp:
58 | with pdfplumber.open(temp, pages=list(range(1, max_pages + 1, 1))) as pdf:
59 | for page in pdf.pages:
60 | page_text = page.extract_text()
61 | pages.append(page_text)
62 | return "\n".join(pages)
63 |
64 | return await asyncio.to_thread(_read_pages)
65 |
66 |
67 | def _image_bytes_to_str(file_bytes: bytes, file_extension: str) -> str:
68 | """
69 | Convert an image to a data URI.
70 | """
71 | data = base64.b64encode(file_bytes).decode("utf-8")
72 | image_type = f"image/{file_extension}"
73 | data_uri = f"data:{image_type};base64,{data}"
74 | return data_uri
75 |
```
--------------------------------------------------------------------------------
/libraries/python/assistant-data-gen/assistant_data_gen/pydantic_ai_utils.py:
--------------------------------------------------------------------------------
```python
1 | # Copyright (c) Microsoft. All rights reserved.
2 |
3 | import os
4 | from typing import Literal
5 |
6 | from azure.identity import DefaultAzureCredential, get_bearer_token_provider
7 | from openai import AsyncAzureOpenAI
8 | from pydantic_ai.models.anthropic import AnthropicModel
9 | from pydantic_ai.models.openai import OpenAIModel
10 | from pydantic_ai.providers.anthropic import AnthropicProvider
11 | from pydantic_ai.providers.openai import OpenAIProvider
12 |
13 |
14 | def get_api_key(provider: str) -> str:
15 | """Get API key for the specified provider."""
16 | env_var = f"{provider.upper()}_API_KEY"
17 | api_key = os.getenv(env_var)
18 | if not api_key:
19 | raise ValueError(f"{env_var} not found in environment variables")
20 | return api_key
21 |
22 |
23 | def create_model(provider: Literal["openai", "anthropic", "azure_openai"]) -> OpenAIModel | AnthropicModel:
24 | """Create a model based on the provider choice. Models are hard-coded because these are the ones that have been tested."""
25 | if provider.lower() == "openai":
26 | api_key = get_api_key(provider)
27 | return OpenAIModel("gpt-4.1", provider=OpenAIProvider(api_key=api_key))
28 | elif provider.lower() == "anthropic":
29 | api_key = get_api_key(provider)
30 | return AnthropicModel("claude-sonnet-4-20250514", provider=AnthropicProvider(api_key=api_key))
31 | elif provider.lower() == "azure_openai":
32 | azure_endpoint = os.getenv("ASSISTANT__AZURE_OPENAI_ENDPOINT")
33 | if not azure_endpoint:
34 | raise ValueError(
35 | "ASSISTANT__AZURE_OPENAI_ENDPOINT environment variable is required for azure_openai provider"
36 | )
37 | azure_credential = DefaultAzureCredential()
38 | azure_ad_token_provider = get_bearer_token_provider(
39 | azure_credential, "https://cognitiveservices.azure.com/.default"
40 | )
41 | azure_client = AsyncAzureOpenAI(
42 | azure_endpoint=azure_endpoint,
43 | azure_ad_token_provider=azure_ad_token_provider,
44 | api_version="2025-04-01-preview",
45 | )
46 | return OpenAIModel("gpt-4.1", provider=OpenAIProvider(openai_client=azure_client))
47 | else:
48 | raise ValueError(f"Unsupported provider: {provider}. Choose 'openai', 'anthropic', or 'azure_openai'")
49 |
```
--------------------------------------------------------------------------------
/assistants/knowledge-transfer-assistant/.vscode/settings.json:
--------------------------------------------------------------------------------
```json
1 | {
2 | "editor.bracketPairColorization.enabled": true,
3 | "editor.codeActionsOnSave": {
4 | "source.organizeImports": "explicit",
5 | "source.fixAll": "explicit"
6 | },
7 | "editor.guides.bracketPairs": "active",
8 | "editor.formatOnPaste": true,
9 | "editor.formatOnType": true,
10 | "editor.formatOnSave": true,
11 | "files.eol": "\n",
12 | "files.exclude": {
13 | "**/.git": true,
14 | "**/.svn": true,
15 | "**/.hg": true,
16 | "**/CVS": true,
17 | "**/.DS_Store": true,
18 | "**/Thumbs.db": true
19 | },
20 | "files.trimTrailingWhitespace": true,
21 | "[json]": {
22 | "editor.defaultFormatter": "esbenp.prettier-vscode",
23 | "editor.formatOnSave": true
24 | },
25 | "[jsonc]": {
26 | "editor.defaultFormatter": "esbenp.prettier-vscode",
27 | "editor.formatOnSave": true
28 | },
29 | "python.analysis.autoFormatStrings": true,
30 | "python.analysis.autoImportCompletions": true,
31 | "python.analysis.diagnosticMode": "workspace",
32 | "python.analysis.fixAll": ["source.unusedImports"],
33 | "python.analysis.inlayHints.functionReturnTypes": true,
34 | "python.defaultInterpreterPath": "${workspaceFolder}/.venv",
35 | "[python]": {
36 | "editor.defaultFormatter": "charliermarsh.ruff",
37 | "editor.formatOnSave": true,
38 | "editor.codeActionsOnSave": {
39 | "source.fixAll": "explicit",
40 | "source.unusedImports": "explicit",
41 | "source.organizeImports": "explicit",
42 | "source.formatDocument": "explicit"
43 | }
44 | },
45 | "ruff.nativeServer": "on",
46 | "search.exclude": {
47 | "**/.venv": true,
48 | "**/.data": true,
49 | "**/__pycache__": true
50 | },
51 |
52 | // For use with optional extension: "streetsidesoftware.code-spell-checker"
53 | "cSpell.ignorePaths": [
54 | ".venv",
55 | "node_modules",
56 | "package-lock.json",
57 | "settings.json",
58 | "uv.lock"
59 | ],
60 | "cSpell.words": [
61 | "Codespaces",
62 | "contentsafety",
63 | "debugpy",
64 | "deepmerge",
65 | "devcontainer",
66 | "dotenv",
67 | "endregion",
68 | "Excalidraw",
69 | "fastapi",
70 | "GIPHY",
71 | "jsonschema",
72 | "Langchain",
73 | "modelcontextprotocol",
74 | "moderations",
75 | "mzxrai",
76 | "openai",
77 | "pdfplumber",
78 | "pydantic",
79 | "pyproject",
80 | "pyright",
81 | "pytest",
82 | "semanticworkbench",
83 | "semanticworkbenchteam",
84 | "tiktoken",
85 | "updown",
86 | "virtualenvs",
87 | "webresearch"
88 | ]
89 | }
90 |
```
--------------------------------------------------------------------------------
/.github/workflows/mcp-server-open-deep-research-clone.yml:
--------------------------------------------------------------------------------
```yaml
1 | name: mcp-server-open-deep-research-clone continuous integration
2 |
3 | permissions:
4 | contents: read
5 | pull-requests: write
6 |
7 | on:
8 | pull_request:
9 | branches: ["main"]
10 | paths:
11 | - "mcp-servers/mcp-server-open-deep-research-clone/**"
12 | - "libraries/python/**"
13 | - "tools/docker/**"
14 | - ".github/workflows/mcp-server-open-deep-research-clone.yml"
15 |
16 | push:
17 | branches: ["main"]
18 | paths:
19 | - "mcp-servers/mcp-server-open-deep-research-clone/**"
20 | - "libraries/python/**"
21 | - "tools/docker/**"
22 | - ".github/workflows/mcp-server-open-deep-research-clone.yml"
23 |
24 | workflow_dispatch:
25 |
26 | defaults:
27 | run:
28 | working-directory: mcp-servers/mcp-server-open-deep-research-clone
29 |
30 | jobs:
31 | test:
32 | runs-on: ubuntu-latest
33 | steps:
34 | - uses: actions/checkout@v4
35 |
36 | - name: Install uv
37 | uses: astral-sh/setup-uv@v3
38 |
39 | - name: Set up Python 3.11
40 | run: uv python install 3.11
41 |
42 | - name: test
43 | run: |
44 | make test
45 |
46 | build:
47 | runs-on: ubuntu-latest
48 | steps:
49 | - uses: actions/checkout@v4
50 |
51 | - name: docker-build
52 | run: |
53 | make docker-build
54 |
55 | deploy:
56 | runs-on: ubuntu-latest
57 | environment: production
58 | permissions:
59 | id-token: write # for OIDC login
60 | contents: read
61 | concurrency:
62 | group: ${{ github.workflow }}-${{ github.ref }}
63 | needs: [build, test]
64 | if: ${{ (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main' && vars.DEPLOYMENT_ENABLED == 'true' }}
65 | env:
66 | DOCKER_IMAGE_TAG: ${{ github.sha }}
67 | DOCKER_REGISTRY_NAME: ${{ secrets.AZURE_CONTAINER_REGISTRY_NAME }}
68 | AZURE_WEBSITE_RESOURCE_GROUP: ${{ secrets.AZURE_WEBSITE_RESOURCE_GROUP }}
69 | AZURE_WEBSITE_SUBSCRIPTION: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
70 |
71 | steps:
72 | - uses: actions/checkout@v4
73 |
74 | - uses: azure/login@v2
75 | with:
76 | client-id: ${{ secrets.AZURE_CLIENT_ID }}
77 | tenant-id: ${{ secrets.AZURE_TENANT_ID }}
78 | subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
79 |
80 | - name: docker-push
81 | run: |
82 | make docker-push
83 |
84 | - name: docker-deploy
85 | run: |
86 | make docker-deploy
87 |
```
--------------------------------------------------------------------------------
/libraries/python/skills/skill-library/skill_library/skills/web_research/routines/visit_pages.py:
--------------------------------------------------------------------------------
```python
1 | from typing import Any
2 |
3 | from openai_client import (
4 | CompletionError,
5 | format_with_liquid,
6 | )
7 | from skill_library import AskUserFn, EmitFn, RunContext, RunRoutineFn
8 | from skill_library.logging import logger
9 |
10 | ASPECT_PROMPT = """
11 | We are conducting thorough research on:
12 | {{TOPIC}}
13 |
14 | Our research plan:
15 |
16 | ```
17 | {{PLAN}}
18 | ```
19 |
20 | Verified facts so far:
21 |
22 | ```
23 | {{FACTS}}
24 | ```
25 |
26 | Previous observations:
27 |
28 | ```
29 | {{OBSERVATIONS}}
30 | ```
31 |
32 | When summarizing this page:
33 | 1. Extract only verifiable information relevant to our research gaps
34 | 2. Include specific technical details, specifications, and quantitative data
35 | 3. Note the reliability of the source and any potential biases
36 | 4. Distinguish between factual statements and opinions/claims
37 | 5. Preserve original terminology and measurements for accuracy
38 | 6. Identify information that contradicts our current understanding
39 | """
40 |
41 |
42 | async def main(
43 | context: RunContext,
44 | routine_state: dict[str, Any],
45 | emit: EmitFn,
46 | run: RunRoutineFn,
47 | ask_user: AskUserFn,
48 | topic: str,
49 | plan: str,
50 | facts: str,
51 | observations: list[str],
52 | urls: list[str] = [],
53 | ) -> str:
54 | """Gather the content from a list of URLs and summarize them according to a particular research project."""
55 |
56 | aspect = format_with_liquid(
57 | ASPECT_PROMPT, vars={"TOPIC": topic, "PLAN": plan, "FACTS": facts, "OBSERVATIONS": "\n- ".join(observations)}
58 | )
59 |
60 | metadata = {}
61 | results = {}
62 | for url in urls[:3]:
63 | try:
64 | content = await run("common.get_content_from_url", url, 10000)
65 | except CompletionError as e:
66 | logger.error(f"Error getting content from {url}: {e}")
67 | metadata[url] = {"fetch error": str(e)}
68 | continue
69 |
70 | try:
71 | summary = await run("common.summarize", content=content, aspect=aspect)
72 | except CompletionError as e:
73 | logger.error(f"Error summarizing content from {url}: {e}")
74 | metadata[url] = {"summarization error": str(e)}
75 | continue
76 |
77 | results[url] = summary
78 | metadata[url] = {"summary": summary}
79 |
80 | context.log("visit_pages", metadata)
81 | return "\n\n".join([f"URL: {url}\nSummary: {summary}" for url, summary in results.items()])
82 |
```
--------------------------------------------------------------------------------
/workbench-app/src/components/App/ContentImport.tsx:
--------------------------------------------------------------------------------
```typescript
1 | // Copyright (c) Microsoft. All rights reserved.
2 |
3 | import { ArrowUploadRegular } from '@fluentui/react-icons';
4 | import React from 'react';
5 | import { CommandButton } from '../App/CommandButton';
6 |
7 | interface ContentImportProps<T> {
8 | contentTypeLabel: string;
9 | importFunction: (file: File) => Promise<T>;
10 | onImport?: (value: T) => void;
11 | onError?: (error: Error) => void;
12 | disabled?: boolean;
13 | iconOnly?: boolean;
14 | asToolbarButton?: boolean;
15 | appearance?: 'primary' | 'secondary' | 'outline' | 'subtle' | 'transparent';
16 | size?: 'small' | 'medium' | 'large';
17 | }
18 |
19 | export const ContentImport = <T extends unknown>(props: ContentImportProps<T>) => {
20 | const {
21 | contentTypeLabel,
22 | importFunction,
23 | onImport,
24 | onError,
25 | disabled,
26 | iconOnly,
27 | asToolbarButton,
28 | appearance,
29 | size,
30 | } = props;
31 | const [uploading, setUploading] = React.useState(false);
32 | const fileInputRef = React.useRef<HTMLInputElement>(null);
33 |
34 | const onFileChange = async (event: React.ChangeEvent<HTMLInputElement>) => {
35 | if (event.target.files) {
36 | setUploading(true);
37 | try {
38 | const file = event.target.files[0];
39 | const content = await importFunction(file);
40 | onImport?.(content);
41 | } catch (error) {
42 | onError?.(error as Error);
43 | }
44 | setUploading(false);
45 | }
46 |
47 | if (fileInputRef.current) {
48 | fileInputRef.current.value = '';
49 | }
50 | };
51 |
52 | const onUpload = async () => {
53 | fileInputRef.current?.click();
54 | };
55 |
56 | return (
57 | <div>
58 | <input hidden ref={fileInputRef} type="file" onChange={onFileChange} />
59 | <CommandButton
60 | disabled={uploading || disabled}
61 | description={`Import ${contentTypeLabel}`}
62 | icon={<ArrowUploadRegular />}
63 | iconOnly={iconOnly}
64 | asToolbarButton={asToolbarButton}
65 | appearance={appearance}
66 | size={size}
67 | label={uploading ? 'Uploading...' : 'Import'}
68 | onClick={onUpload}
69 | />
70 | </div>
71 | );
72 | };
73 |
```
--------------------------------------------------------------------------------
/workbench-app/src/libs/useMediaQuery.ts:
--------------------------------------------------------------------------------
```typescript
1 | import React from 'react';
2 |
3 | export const useMediaQuery = (config: MediaQueryConfig): boolean => {
4 | const query = buildMediaQuery(config);
5 | const [matches, setMatches] = React.useState<boolean>(false);
6 |
7 | React.useEffect(() => {
8 | const mediaQueryList = window.matchMedia(query);
9 | const documentChangeHandler = () => setMatches(mediaQueryList.matches);
10 |
11 | // Set the initial state
12 | documentChangeHandler();
13 |
14 | // Listen for changes
15 | mediaQueryList.addEventListener('change', documentChangeHandler);
16 |
17 | return () => {
18 | mediaQueryList.removeEventListener('change', documentChangeHandler);
19 | };
20 | }, [query]);
21 |
22 | return matches;
23 | };
24 |
25 | type MediaQueryConfig =
26 | | { minWidth: string | number }
27 | | { maxWidth: string | number }
28 | | { minHeight: string | number }
29 | | { maxHeight: string | number }
30 | | { query: string }
31 | | { orientation: 'portrait' | 'landscape' }
32 | | { resolution: 'high' }
33 | | { aspectRatio: 'wide' | 'tall' }
34 | | { device: 'screen' | 'print' };
35 |
36 | export const buildMediaQuery = (config: MediaQueryConfig): string => {
37 | if ('minWidth' in config) {
38 | return `(min-width: ${typeof config.minWidth === 'number' ? `${config.minWidth}px` : config.minWidth})`;
39 | }
40 | if ('maxWidth' in config) {
41 | return `(max-width: ${typeof config.maxWidth === 'number' ? `${config.maxWidth}px` : config.maxWidth})`;
42 | }
43 | if ('minHeight' in config) {
44 | return `(min-height: ${typeof config.minHeight === 'number' ? `${config.minHeight}px` : config.minHeight})`;
45 | }
46 | if ('maxHeight' in config) {
47 | return `(max-height: ${typeof config.maxHeight === 'number' ? `${config.maxHeight}px` : config.maxHeight})`;
48 | }
49 | if ('query' in config) {
50 | return config.query;
51 | }
52 | if ('orientation' in config) {
53 | return `(orientation: ${config.orientation})`;
54 | }
55 | if ('resolution' in config) {
56 | return `(min-resolution: 2dppx)`;
57 | }
58 | if ('aspectRatio' in config) {
59 | return config.aspectRatio === 'wide' ? `(min-aspect-ratio: 16/9)` : `(max-aspect-ratio: 1/1)`;
60 | }
61 | if ('device' in config) {
62 | return config.device;
63 | }
64 | return '';
65 | };
66 |
```
--------------------------------------------------------------------------------
/mcp-servers/mcp-server-open-deep-research-clone/mcp_server_open_deep_research_clone/server.py:
--------------------------------------------------------------------------------
```python
1 | from mcp.server.fastmcp import Context, FastMCP
2 | from mcp_extensions import send_tool_call_progress
3 |
4 | from .config import settings
5 | from .web_research import perform_web_research
6 |
7 | # Set the name of the MCP server
8 | server_name = "Web Research MCP Server"
9 |
10 |
11 | def create_mcp_server() -> FastMCP:
12 | # Initialize FastMCP with debug logging.
13 | mcp = FastMCP(name=server_name, log_level=settings.log_level)
14 |
15 | # Define each tool and its setup.
16 |
17 | # Example tool
18 | @mcp.tool()
19 | async def echo(value: str) -> str:
20 | """
21 | Will return whatever is passed to it.
22 | """
23 |
24 | return value
25 |
26 | @mcp.tool()
27 | async def web_research(context: str, request: str, ctx: Context) -> str:
28 | """
29 | A specialized team member that thoroughly researches the internet to answer your questions.
30 | Use them for anything requiring web browsing—provide as much context as possible, especially
31 | if you need to research a specific timeframe. Don’t hesitate to give complex tasks, like
32 | analyzing differences between products or spotting discrepancies between sources. Your
33 | request must be full sentences, not just search terms (e.g., “Research current trends for…”
34 | instead of a few keywords). For context, pass as much background as you can: if using this
35 | tool in a conversation, include the conversation history; if in a broader context, include
36 | any relevant documents or details. If there is no context, pass “None.” Finally, for the
37 | request itself, provide the specific question you want answered, with as much detail as
38 | possible about what you need and the desired output.
39 | """
40 |
41 | await send_tool_call_progress(ctx, "Researching...", data={"context": context, "request": request})
42 |
43 | async def on_status_update(status: str) -> None:
44 | await send_tool_call_progress(ctx, status)
45 |
46 | # Make sure to run the async version of the function to avoid blocking the event loop.
47 | deep_research_result = await perform_web_research(
48 | question=f"Context:\n{context}\n\nRequest:\n{request}", on_status_update=on_status_update
49 | )
50 | return deep_research_result
51 |
52 | return mcp
53 |
```
--------------------------------------------------------------------------------
/libraries/python/semantic-workbench-assistant/semantic_workbench_assistant/auth.py:
--------------------------------------------------------------------------------
```python
1 | import logging
2 | import secrets
3 |
4 | from fastapi import HTTPException, Request, Response, status
5 | from fastapi.responses import JSONResponse
6 | from semantic_workbench_api_model import assistant_service_client
7 | from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint
8 | from starlette.types import ASGIApp
9 |
10 | from . import settings
11 |
12 | logger = logging.getLogger(__name__)
13 |
14 |
15 | class AuthMiddleware(BaseHTTPMiddleware):
16 | def __init__(self, app: ASGIApp, exclude_methods: set[str] = set(), exclude_paths: set[str] = set()) -> None:
17 | super().__init__(app)
18 | self.exclude_methods = exclude_methods
19 | self.exclude_routes = exclude_paths
20 |
21 | async def dispatch(self, request: Request, call_next: RequestResponseEndpoint) -> Response:
22 | if request.method in self.exclude_methods:
23 | return await call_next(request)
24 |
25 | if request.url.path in self.exclude_routes:
26 | return await call_next(request)
27 |
28 | try:
29 | await _require_api_key(request)
30 |
31 | except HTTPException as exc:
32 | # if the authorization header is invalid, return the error response
33 | return JSONResponse(content={"detail": exc.detail}, status_code=exc.status_code)
34 | except Exception:
35 | logger.exception("error validating authorization header")
36 | # return a generic error response
37 | return Response(status_code=500)
38 |
39 | return await call_next(request)
40 |
41 |
42 | async def _require_api_key(request: Request) -> None:
43 | invalid_credentials_error = HTTPException(
44 | status_code=status.HTTP_401_UNAUTHORIZED,
45 | detail="Invalid credentials",
46 | headers={"WWW-Authenticate": "Basic"},
47 | )
48 |
49 | params = assistant_service_client.AuthParams.from_request_headers(request.headers)
50 | api_key = params.api_key
51 | if not api_key:
52 | if settings.workbench_service_api_key:
53 | raise invalid_credentials_error
54 | return
55 |
56 | password_bytes = api_key.encode("utf8")
57 | correct_password_bytes = settings.workbench_service_api_key.encode("utf8")
58 | is_correct_password = secrets.compare_digest(password_bytes, correct_password_bytes)
59 |
60 | if not is_correct_password:
61 | raise invalid_credentials_error
62 |
```
--------------------------------------------------------------------------------
/workbench-app/src/components/Conversations/ConversationShare.tsx:
--------------------------------------------------------------------------------
```typescript
1 | // Copyright (c) Microsoft. All rights reserved.
2 |
3 | import { Share24Regular } from '@fluentui/react-icons';
4 | import React from 'react';
5 | import { Conversation } from '../../models/Conversation';
6 | import { CommandButton } from '../App/CommandButton';
7 | import { DialogControl } from '../App/DialogControl';
8 | import { ConversationShareList } from './ConversationShareList';
9 |
10 | const useConversationShareControls = () => {
11 | return {
12 | shareConversationForm: React.useCallback(
13 | (conversation: Conversation) => (
14 | <p>
15 | <ConversationShareList conversation={conversation} />
16 | </p>
17 | ),
18 | [],
19 | ),
20 | };
21 | };
22 |
23 | interface ConversationShareDialogProps {
24 | conversation: Conversation;
25 | onClose: () => void;
26 | }
27 |
28 | export const ConversationShareDialog: React.FC<ConversationShareDialogProps> = (props) => {
29 | const { conversation, onClose } = props;
30 | const { shareConversationForm } = useConversationShareControls();
31 |
32 | return (
33 | <DialogControl
34 | open={true}
35 | onOpenChange={onClose}
36 | title="Share conversation"
37 | content={shareConversationForm(conversation)}
38 | />
39 | );
40 | };
41 |
42 | interface ConversationShareProps {
43 | conversation: Conversation;
44 | iconOnly?: boolean;
45 | asToolbarButton?: boolean;
46 | }
47 |
48 | export const ConversationShare: React.FC<ConversationShareProps> = (props) => {
49 | const { conversation, iconOnly, asToolbarButton } = props;
50 | if (!conversation) {
51 | throw new Error('ConversationId is required');
52 | }
53 |
54 | const { shareConversationForm } = useConversationShareControls();
55 |
56 | const readOnly = conversation.conversationPermission !== 'read_write';
57 |
58 | const dialogContent = readOnly
59 | ? undefined
60 | : {
61 | title: 'Manage Shares for Conversation',
62 | content: shareConversationForm(conversation),
63 | };
64 |
65 | return (
66 | <CommandButton
67 | icon={<Share24Regular />}
68 | iconOnly={iconOnly}
69 | disabled={readOnly}
70 | asToolbarButton={asToolbarButton}
71 | label="Share"
72 | description="Share conversation"
73 | dialogContent={dialogContent}
74 | />
75 | );
76 | };
77 |
```
--------------------------------------------------------------------------------
/assistants/document-assistant/assistant/response/utils/formatting_utils.py:
--------------------------------------------------------------------------------
```python
1 | # Copyright (c) Microsoft. All rights reserved.
2 |
3 | import logging
4 | from textwrap import dedent
5 |
6 | import pendulum
7 | from semantic_workbench_api_model.workbench_model import (
8 | ConversationMessage,
9 | ConversationParticipant,
10 | )
11 |
12 | logger = logging.getLogger(__name__)
13 |
14 |
15 | def format_message(message: ConversationMessage, participants: list[ConversationParticipant]) -> str:
16 | """
17 | Format a conversation message for display.
18 | """
19 | conversation_participant = next(
20 | (participant for participant in participants if participant.id == message.sender.participant_id),
21 | None,
22 | )
23 | participant_name = conversation_participant.name if conversation_participant else "unknown"
24 | message_datetime = pendulum.instance(message.timestamp, tz="America/Los_Angeles")
25 | message_datetime = message_datetime.format("Y-MM-DD HH:mm:ss")
26 | return f"[{participant_name} - {message_datetime}]: {message.content}"
27 |
28 |
29 | def get_response_duration_message(response_duration: float) -> str:
30 | """
31 | Generate a display friendly message for the response duration, to be added to the footer items.
32 | """
33 |
34 | return f"Response time: {response_duration:.2f} seconds"
35 |
36 |
37 | def get_formatted_token_count(tokens: int) -> str:
38 | # if less than 1k, return the number of tokens
39 | # if greater than or equal to 1k, return the number of tokens in k
40 | # use 1 decimal place for k
41 | # drop the decimal place if the number of tokens in k is a whole number
42 | if tokens < 1000:
43 | return str(tokens)
44 | else:
45 | tokens_in_k = tokens / 1000
46 | if tokens_in_k.is_integer():
47 | return f"{int(tokens_in_k)}k"
48 | else:
49 | return f"{tokens_in_k:.1f}k"
50 |
51 |
52 | def get_token_usage_message(
53 | max_tokens: int,
54 | total_tokens: int,
55 | request_tokens: int,
56 | completion_tokens: int,
57 | ) -> str:
58 | """
59 | Generate a display friendly message for the token usage, to be added to the footer items.
60 | """
61 |
62 | return dedent(f"""
63 | Tokens used: {get_formatted_token_count(total_tokens)}
64 | ({get_formatted_token_count(request_tokens)} in / {get_formatted_token_count(completion_tokens)} out)
65 | of {get_formatted_token_count(max_tokens)} ({int(total_tokens / max_tokens * 100)}%)
66 | """).strip()
67 |
```
--------------------------------------------------------------------------------
/assistants/knowledge-transfer-assistant/docs/knowledge-transfer-goals.md:
--------------------------------------------------------------------------------
```markdown
1 | # Goals for the Knowledge Transfer Assistant
2 |
3 | ## Core idea
4 |
5 | Assist users in synthesizing knowledge from data and ideas and transfer that knowledge to others.
6 |
7 | ## Shortcomings of existing solutions
8 |
9 | - Even though assistants can help do this well, it normally requires the user to have the idea to use an assistant this way and to guide the assistant through the process.
10 | - While we had previously used shared (single) assistant conversations to do this, it was confusing for users to all work in the same conversation.
11 | - Users could opt to instead create a copy of the original conversation, but that suffered due to the fact that it was now disconnected from any ongoing development in each of the conversations.
12 |
13 | ## Our solution
14 |
15 | ### Give both knowledge producers and knowledge learners individual conversations
16 |
17 | This solution addresses all of these items with a creative take on the scenario through separate conversations with an assistant that has built-in guidance and ability to work across all of the conversations.
18 |
19 | Splitting the producer/consumer (or coordinator/team) conversations unlocked many more interesting benefits:
20 |
21 | - Multiple producers can collaborate within a single conversation to set up the knowledge share.
22 | - The knowledge share can be transferred to multiple recipients.
23 | - Since each conversation has its own assistant, we have the assistants manage communication between producers and consumers through "information requests".
24 | - Each conversation assistant can adopt a communication style preferred by it's users.
25 |
26 | ### Learning progress
27 |
28 | In order to guide consumers through the knowledge transfer experience, we introduced the idea of "learning objectives" and "learning outcomes". The producer and their assistant can define what objectives and outcomes they desire their learning audience to achieve. The learners are assisted by their assistant in achieving those outcomes. The assistants guide them through their material at a pace and way that they prefer. When learners achieve outcomes, the producers are notified. This provides clear feedback to all parties of the progression through the knowledge transfer.
29 |
30 | ## Read more about the problem space
31 |
32 | See [Knowledge Transfer Jobs-to-be-done](./JTBD.md)
33 |
```
--------------------------------------------------------------------------------
/assistants/project-assistant/docs/knowledge-transfer-goals.md:
--------------------------------------------------------------------------------
```markdown
1 | # Goals for the Knowledge Transfer Assistant
2 |
3 | ## Core idea
4 |
5 | Assist users in synthesizing knowledge from data and ideas and transfer that knowledge to others.
6 |
7 | ## Shortcomings of existing solutions
8 |
9 | - Even though assistants can help do this well, it normally requires the user to have the idea to use an assistant this way and to guide the assistant through the process.
10 | - While we had previously used shared (single) assistant conversations to do this, it was confusing for users to all work in the same conversation.
11 | - Users could opt to instead create a copy of the original conversation, but that suffered due to the fact that it was now disconnected from any ongoing development in each of the conversations.
12 |
13 | ## Our solution
14 |
15 | ### Give both knowledge producers and knowledge learners individual conversations
16 |
17 | This solution addresses all of these items with a creative take on the scenario through separate conversations with an assistant that has built-in guidance and ability to work across all of the conversations.
18 |
19 | Splitting the producer/consumer (or coordinator/team) conversations unlocked many more interesting benefits:
20 |
21 | - Multiple producers can collaborate within a single conversation to set up the knowledge share.
22 | - The knowledge share can be transferred to multiple recipients.
23 | - Since each conversation has its own assistant, we have the assistants manage communication between producers and consumers through "information requests".
24 | - Each conversation assistant can adopt a communication style preferred by it's users.
25 |
26 | ### Learning progress
27 |
28 | In order to guide consumers through the knowledge transfer experience, we introduced the idea of "learning objectives" and "learning outcomes". The producer and their assistant can define what objectives and outcomes they desire their learning audience to achieve. The learners are assisted by their assistant in achieving those outcomes. The assistants guide them through their material at a pace and way that they prefer. When learners achieve outcomes, the producers are notified. This provides clear feedback to all parties of the progression through the knowledge transfer.
29 |
30 | ## Read more about the problem space
31 |
32 | See [Knowledge Transfer Jobs-to-be-done](./JTBD.md)
33 |
```
--------------------------------------------------------------------------------
/assistants/project-assistant/tests/test_inspector.py:
--------------------------------------------------------------------------------
```python
1 | """
2 | Test script to verify state inspector functionality.
3 | """
4 |
5 | import asyncio
6 | import logging
7 | from unittest.mock import AsyncMock, MagicMock
8 |
9 | from assistant.assistant import assistant
10 | from semantic_workbench_api_model.workbench_model import AssistantStateEvent
11 | from semantic_workbench_assistant.assistant_app import ConversationContext
12 |
13 | # Set up logging
14 | logging.basicConfig(level=logging.INFO)
15 | logger = logging.getLogger(__name__)
16 |
17 |
18 | async def test_inspector():
19 | """Test the state inspector provider."""
20 | # Create mock context
21 | context = AsyncMock(spec=ConversationContext)
22 | context.id = "test-conversation-id"
23 | context.assistant = MagicMock()
24 | context.assistant.id = "test-assistant-id"
25 |
26 | # Mock conversation
27 | conversation = MagicMock()
28 | conversation.metadata = {
29 | "setup_complete": True,
30 | "assistant_mode": "coordinator",
31 | "share_role": "coordinator",
32 | }
33 | context.get_conversation.return_value = conversation
34 |
35 | # Test all four tabbed inspectors
36 | inspector_ids = [
37 | "brief",
38 | "objectives",
39 | "requests",
40 | "debug",
41 | ] # Note: "requests" tab now shows as "Sharing"
42 |
43 | for inspector_id in inspector_ids:
44 | logger.info(f"Testing {inspector_id} inspector...")
45 |
46 | # Create state event
47 | state_event = AssistantStateEvent(state_id=inspector_id, event="focus", state=None)
48 |
49 | # Send event
50 | logger.info("Sending state event...")
51 | await context.send_conversation_state_event(state_event)
52 |
53 | # Get inspector provider
54 | inspector_provider = assistant.inspector_state_providers.get(inspector_id)
55 | if not inspector_provider:
56 | logger.error(f"No {inspector_id} inspector provider found!")
57 | continue
58 |
59 | logger.info(f"Inspector provider found: {inspector_provider.display_name}")
60 |
61 | # Get state data
62 | try:
63 | state_data = await inspector_provider.get(context)
64 | logger.info(f"State data: {state_data}")
65 | except Exception as e:
66 | logger.error(f"Error getting state data: {e}")
67 |
68 | logger.info(f"--- {inspector_id} inspector test completed ---")
69 |
70 |
71 | # Run the test
72 | if __name__ == "__main__":
73 | asyncio.run(test_inspector())
74 |
```
--------------------------------------------------------------------------------
/libraries/python/skills/skill-library/skill_library/skills/fabric/patterns/answer_interview_question/system.md:
--------------------------------------------------------------------------------
```markdown
1 | # IDENTITY
2 |
3 | You are a versatile AI designed to help candidates excel in technical interviews. Your key strength lies in simulating practical, conversational responses that reflect both depth of knowledge and real-world experience. You analyze interview questions thoroughly to generate responses that are succinct yet comprehensive, showcasing the candidate's competence and foresight in their field.
4 |
5 | # GOAL
6 |
7 | Generate tailored responses to technical interview questions that are approximately 30 seconds long when spoken. Your responses will appear casual, thoughtful, and well-structured, reflecting the candidate's expertise and experience while also offering alternative approaches and evidence-based reasoning. Do not speculate or guess at answers.
8 |
9 | # STEPS
10 |
11 | - Receive and parse the interview question to understand the core topics and required expertise.
12 |
13 | - Draw from a database of technical knowledge and professional experiences to construct a first-person response that reflects a deep understanding of the subject.
14 |
15 | - Include an alternative approach or idea that the interviewee considered, adding depth to the response.
16 |
17 | - Incorporate at least one piece of evidence or an example from past experience to substantiate the response.
18 |
19 | - Ensure the response is structured to be clear and concise, suitable for a verbal delivery within 30 seconds.
20 |
21 | # OUTPUT
22 |
23 | - The output will be a direct first-person response to the interview question. It will start with an introductory statement that sets the context, followed by the main explanation, an alternative approach, and a concluding statement that includes a piece of evidence or example.
24 |
25 | # EXAMPLE
26 |
27 | INPUT: "Can you describe how you would manage project dependencies in a large software development project?"
28 |
29 | OUTPUT:
30 | "In my last project, where I managed a team of developers, we used Docker containers to handle dependencies efficiently. Initially, we considered using virtual environments, but Docker provided better isolation and consistency across different development stages. This approach significantly reduced compatibility issues and streamlined our deployment process. In fact, our deployment time was cut by about 30%, which was a huge win for us."
31 |
32 | # INPUT
33 |
34 | INPUT:
35 |
36 |
```
--------------------------------------------------------------------------------
/workbench-service/semantic_workbench_service/auth.py:
--------------------------------------------------------------------------------
```python
1 | import uuid
2 | from contextvars import ContextVar
3 | from dataclasses import dataclass
4 | from typing import Annotated
5 |
6 | from fastapi import Depends, HTTPException, status
7 |
8 |
9 | @dataclass
10 | class AssistantServicePrincipal:
11 | assistant_service_id: str
12 |
13 |
14 | @dataclass
15 | class UserPrincipal:
16 | user_id: str
17 | name: str
18 |
19 |
20 | @dataclass
21 | class AssistantPrincipal(AssistantServicePrincipal):
22 | assistant_id: uuid.UUID
23 |
24 |
25 | class ServiceUserPrincipal(UserPrincipal):
26 | pass
27 |
28 |
29 | Principal = UserPrincipal | AssistantServicePrincipal
30 |
31 | authenticated_principal: ContextVar[Principal | None] = ContextVar("request_principal", default=None)
32 |
33 |
34 | def _request_principal() -> Principal:
35 | # the principal is stored in the request state by middle-ware
36 | principal = authenticated_principal.get()
37 | if principal is None:
38 | raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
39 | return principal
40 |
41 |
42 | DependsPrincipal = Annotated[Principal, Depends(_request_principal)]
43 |
44 |
45 | ActorPrincipal = UserPrincipal | AssistantPrincipal
46 |
47 |
48 | def _actor_principal(principal: DependsPrincipal) -> ActorPrincipal:
49 | if not isinstance(principal, ActorPrincipal):
50 | raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
51 | return principal
52 |
53 |
54 | DependsActorPrincipal = Annotated[ActorPrincipal, Depends(_actor_principal)]
55 |
56 |
57 | def _user_principal(principal: DependsPrincipal) -> UserPrincipal:
58 | if isinstance(principal, UserPrincipal):
59 | return principal
60 | raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
61 |
62 |
63 | def _assistant_service_principal(principal: DependsPrincipal) -> AssistantServicePrincipal:
64 | if isinstance(principal, AssistantServicePrincipal):
65 | return principal
66 | raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
67 |
68 |
69 | def _assistant_principal(principal: DependsPrincipal) -> AssistantPrincipal:
70 | if isinstance(principal, AssistantPrincipal):
71 | return principal
72 | raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)
73 |
74 |
75 | DependsAssistantServicePrincipal = Annotated[AssistantServicePrincipal, Depends(_assistant_service_principal)]
76 | DependsAssistantPrincipal = Annotated[AssistantPrincipal, Depends(_assistant_principal)]
77 | DependsUserPrincipal = Annotated[UserPrincipal, Depends(_user_principal)]
78 |
```
--------------------------------------------------------------------------------
/assistants/codespace-assistant/.vscode/settings.json:
--------------------------------------------------------------------------------
```json
1 | {
2 | "editor.bracketPairColorization.enabled": true,
3 | "editor.codeActionsOnSave": {
4 | "source.organizeImports": "explicit",
5 | "source.fixAll": "explicit"
6 | },
7 | "editor.guides.bracketPairs": "active",
8 | "editor.formatOnPaste": true,
9 | "editor.formatOnType": true,
10 | "editor.formatOnSave": true,
11 | "files.eol": "\n",
12 | "files.exclude": {
13 | "**/.git": true,
14 | "**/.svn": true,
15 | "**/.hg": true,
16 | "**/CVS": true,
17 | "**/.DS_Store": true,
18 | "**/Thumbs.db": true
19 | },
20 | "files.trimTrailingWhitespace": true,
21 | "[json]": {
22 | "editor.defaultFormatter": "esbenp.prettier-vscode",
23 | "editor.formatOnSave": true
24 | },
25 | "[jsonc]": {
26 | "editor.defaultFormatter": "esbenp.prettier-vscode",
27 | "editor.formatOnSave": true
28 | },
29 | "python.analysis.autoFormatStrings": true,
30 | "python.analysis.autoImportCompletions": true,
31 | "python.analysis.diagnosticMode": "workspace",
32 | "python.analysis.fixAll": ["source.unusedImports"],
33 | "python.analysis.inlayHints.functionReturnTypes": true,
34 | "python.analysis.typeCheckingMode": "standard",
35 | "python.defaultInterpreterPath": "${workspaceFolder}/.venv",
36 | "[python]": {
37 | "editor.defaultFormatter": "charliermarsh.ruff",
38 | "editor.formatOnSave": true,
39 | "editor.codeActionsOnSave": {
40 | "source.fixAll": "explicit",
41 | "source.unusedImports": "explicit",
42 | "source.organizeImports": "explicit",
43 | "source.formatDocument": "explicit"
44 | }
45 | },
46 | "ruff.nativeServer": "on",
47 | "search.exclude": {
48 | "**/.venv": true,
49 | "**/.data": true,
50 | "**/__pycache__": true
51 | },
52 |
53 | // For use with optional extension: "streetsidesoftware.code-spell-checker"
54 | "cSpell.ignorePaths": [
55 | ".venv",
56 | "node_modules",
57 | "package-lock.json",
58 | "settings.json",
59 | "uv.lock"
60 | ],
61 | "cSpell.words": [
62 | "Codespaces",
63 | "contentsafety",
64 | "debugpy",
65 | "deepmerge",
66 | "devcontainer",
67 | "dotenv",
68 | "endregion",
69 | "Excalidraw",
70 | "fastapi",
71 | "GIPHY",
72 | "jsonschema",
73 | "Langchain",
74 | "modelcontextprotocol",
75 | "moderations",
76 | "mzxrai",
77 | "openai",
78 | "pdfplumber",
79 | "pydantic",
80 | "pyproject",
81 | "pyright",
82 | "pytest",
83 | "semanticworkbench",
84 | "semanticworkbenchteam",
85 | "tiktoken",
86 | "updown",
87 | "virtualenvs",
88 | "webresearch"
89 | ]
90 | }
91 |
```
--------------------------------------------------------------------------------
/assistants/navigator-assistant/.vscode/settings.json:
--------------------------------------------------------------------------------
```json
1 | {
2 | "editor.bracketPairColorization.enabled": true,
3 | "editor.codeActionsOnSave": {
4 | "source.organizeImports": "explicit",
5 | "source.fixAll": "explicit"
6 | },
7 | "editor.guides.bracketPairs": "active",
8 | "editor.formatOnPaste": true,
9 | "editor.formatOnType": true,
10 | "editor.formatOnSave": true,
11 | "files.eol": "\n",
12 | "files.exclude": {
13 | "**/.git": true,
14 | "**/.svn": true,
15 | "**/.hg": true,
16 | "**/CVS": true,
17 | "**/.DS_Store": true,
18 | "**/Thumbs.db": true
19 | },
20 | "files.trimTrailingWhitespace": true,
21 | "[json]": {
22 | "editor.defaultFormatter": "esbenp.prettier-vscode",
23 | "editor.formatOnSave": true
24 | },
25 | "[jsonc]": {
26 | "editor.defaultFormatter": "esbenp.prettier-vscode",
27 | "editor.formatOnSave": true
28 | },
29 | "python.analysis.autoFormatStrings": true,
30 | "python.analysis.autoImportCompletions": true,
31 | "python.analysis.diagnosticMode": "workspace",
32 | "python.analysis.fixAll": ["source.unusedImports"],
33 | "python.analysis.inlayHints.functionReturnTypes": true,
34 | "python.analysis.typeCheckingMode": "standard",
35 | "python.defaultInterpreterPath": "${workspaceFolder}/.venv",
36 | "[python]": {
37 | "editor.defaultFormatter": "charliermarsh.ruff",
38 | "editor.formatOnSave": true,
39 | "editor.codeActionsOnSave": {
40 | "source.fixAll": "explicit",
41 | "source.unusedImports": "explicit",
42 | "source.organizeImports": "explicit",
43 | "source.formatDocument": "explicit"
44 | }
45 | },
46 | "ruff.nativeServer": "on",
47 | "search.exclude": {
48 | "**/.venv": true,
49 | "**/.data": true,
50 | "**/__pycache__": true
51 | },
52 |
53 | // For use with optional extension: "streetsidesoftware.code-spell-checker"
54 | "cSpell.ignorePaths": [
55 | ".venv",
56 | "node_modules",
57 | "package-lock.json",
58 | "settings.json",
59 | "uv.lock"
60 | ],
61 | "cSpell.words": [
62 | "Codespaces",
63 | "contentsafety",
64 | "debugpy",
65 | "deepmerge",
66 | "devcontainer",
67 | "dotenv",
68 | "endregion",
69 | "Excalidraw",
70 | "fastapi",
71 | "GIPHY",
72 | "jsonschema",
73 | "Langchain",
74 | "modelcontextprotocol",
75 | "moderations",
76 | "mzxrai",
77 | "openai",
78 | "pdfplumber",
79 | "pydantic",
80 | "pyproject",
81 | "pyright",
82 | "pytest",
83 | "semanticworkbench",
84 | "semanticworkbenchteam",
85 | "tiktoken",
86 | "updown",
87 | "virtualenvs",
88 | "webresearch"
89 | ]
90 | }
91 |
```