#
tokens: 46426/50000 3/1784 files (page 88/145)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 88 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

--------------------------------------------------------------------------------
/assistants/prospector-assistant/assistant/form_fill_extension/steps/fill_form_step.py:
--------------------------------------------------------------------------------

```python
  1 | import logging
  2 | from contextlib import asynccontextmanager
  3 | from dataclasses import dataclass
  4 | from pathlib import Path
  5 | from textwrap import dedent
  6 | from typing import Annotated, Any, AsyncIterator, Literal, Optional
  7 | 
  8 | from guided_conversation.utils.resources import ResourceConstraintMode, ResourceConstraintUnit
  9 | from openai.types.chat import ChatCompletionMessageParam
 10 | from pydantic import BaseModel, ConfigDict, Field, create_model
 11 | from semantic_workbench_assistant.assistant_app.context import ConversationContext, storage_directory_for_context
 12 | from semantic_workbench_assistant.assistant_app.protocol import AssistantAppProtocol
 13 | from semantic_workbench_assistant.config import UISchema
 14 | 
 15 | from .. import state
 16 | from ..inspector import FileStateInspector
 17 | from . import _guided_conversation, _llm
 18 | from .types import (
 19 |     Context,
 20 |     GuidedConversationDefinition,
 21 |     IncompleteErrorResult,
 22 |     IncompleteResult,
 23 |     LLMConfig,
 24 |     ResourceConstraintDefinition,
 25 |     Result,
 26 | )
 27 | 
 28 | logger = logging.getLogger(__name__)
 29 | 
 30 | 
 31 | def extend(app: AssistantAppProtocol) -> None:
 32 |     app.add_inspector_state_provider(_guided_conversation_inspector.state_id, _guided_conversation_inspector)
 33 |     app.add_inspector_state_provider(_populated_form_state_inspector.state_id, _populated_form_state_inspector)
 34 | 
 35 | 
 36 | definition = GuidedConversationDefinition(
 37 |     rules=[
 38 |         "When kicking off the conversation, do not greet the user with Hello or other greetings.",
 39 |         "For fields that are not in the provided files, collect the data from the user through conversation.",
 40 |         "When providing options for a multiple choice field, provide the options in a numbered-list, so the user can refer to them by number.",
 41 |         "When listing anything other than options, like document types, provide them in a bulleted list for improved readability.",
 42 |         "When updating the agenda, the data-collection for each form field must be in a separate step.",
 43 |         "When asking for data to fill the form, always ask for a single piece of information at a time. Never ask for multiple pieces of information in a single prompt, ex: 'Please provide field Y, and additionally, field X'.",
 44 |         "Terminate conversation if inappropriate content is requested.",
 45 |     ],
 46 |     conversation_flow=dedent("""
 47 |         1. Inform the user that we've received the form and determined the fields in the form.
 48 |         2. Inform the user that our goal is help them fill out the form.
 49 |         3. Ask the user to provide one or more files that might contain data relevant to fill out the form. The files can be PDF, TXT, DOCX, or PNG.
 50 |         4. When asking for files, suggest types of documents that might contain the data.
 51 |         5. For each field in the form, check if the data is available in the provided files.
 52 |         6. If the data is not available in the files, ask the user for the data.
 53 |         7. When the form is filled out, inform the user that you will now generate a document containing the filled form.
 54 |     """).strip(),
 55 |     context="",
 56 |     resource_constraint=ResourceConstraintDefinition(
 57 |         quantity=1000,
 58 |         unit=ResourceConstraintUnit.TURNS,
 59 |         mode=ResourceConstraintMode.MAXIMUM,
 60 |     ),
 61 | )
 62 | 
 63 | 
 64 | class ExtractCandidateFieldValuesConfig(BaseModel):
 65 |     instruction: Annotated[
 66 |         str,
 67 |         Field(
 68 |             title="Instruction",
 69 |             description="The instruction for extracting candidate form-field values from an uploaded file",
 70 |         ),
 71 |         UISchema(widget="textarea"),
 72 |     ] = dedent("""
 73 |         Given the field definitions below, extract candidate values for these fields from the user provided
 74 |         attachment.
 75 | 
 76 |         Only include values that are in the provided attachment.
 77 |         It is possible that there are multiple candidates for a single field, in which case you should provide
 78 |         all the candidates and an explanation for each candidate.
 79 | 
 80 |         For example, if their is a field for an individual's name, 'name', and there are multiple names in the
 81 |         attachment, you should provide all the names in the attachment as candidates for the 'name' field.
 82 | 
 83 |         Also, if their are multiple fields for individual's names in the form, 'name_one' and 'name_two', and
 84 |         there are one or more names in the attachment, you should provide all the names in the attachment as
 85 |         candidates for the 'name_one' and 'name_two' field.
 86 | 
 87 |         Field definitions:
 88 |         {{form_fields}}
 89 |     """)
 90 | 
 91 | 
 92 | class FillFormConfig(BaseModel):
 93 |     extract_config: ExtractCandidateFieldValuesConfig = ExtractCandidateFieldValuesConfig()
 94 |     definition: GuidedConversationDefinition = definition
 95 | 
 96 | 
 97 | class FieldValueCandidate(BaseModel):
 98 |     field_id: str = Field(description="The ID of the field that the value is a candidate for.")
 99 |     value: str = Field(description="The value from the document for this field.")
100 |     explanation: str = Field(description="The explanation of why this value is a candidate for the field.")
101 | 
102 | 
103 | class FieldValueCandidates(BaseModel):
104 |     response: str = Field(description="The natural language response to send to the user.")
105 |     fields: list[FieldValueCandidate] = Field(description="The fields in the form.")
106 | 
107 | 
108 | class FieldValueCandidatesFromDocument(BaseModel):
109 |     filename: str
110 |     candidates: FieldValueCandidates
111 | 
112 | 
113 | class FillFormState(BaseModel):
114 |     populated_form_markdown: str = "(The form has not yet been provided)"
115 | 
116 | 
117 | @dataclass
118 | class CompleteResult(Result):
119 |     message: str
120 |     artifact: dict
121 |     populated_form_markdown: str
122 | 
123 | 
124 | async def execute(
125 |     step_context: Context[FillFormConfig],
126 |     form_filename: str,
127 |     form: state.Form,
128 | ) -> IncompleteResult | IncompleteErrorResult | CompleteResult:
129 |     """
130 |     Step: fill out the form with the user through conversation and pulling values from uploaded attachments.
131 |     Approach: Guided conversation / direct chat-completion (for document extraction)
132 |     """
133 | 
134 |     def fields_for(section: state.Section) -> list[state.FormField]:
135 |         form_fields = section.fields.copy()
136 |         for sub_section in section.sections:
137 |             form_fields.extend(fields_for(sub_section))
138 |         return form_fields
139 | 
140 |     form_fields = fields_for(form)
141 | 
142 |     debug = {}
143 | 
144 |     message_part, message_debug = await _candidate_values_from_attachments_as_message_part(
145 |         step_context, form_filename, form_fields
146 |     )
147 | 
148 |     message = "\n".join((step_context.latest_user_input.message or "", message_part))
149 |     if message_debug:
150 |         debug["document-extractions"] = message_debug
151 | 
152 |     artifact_type = _form_fields_to_artifact_basemodel(form_fields)
153 | 
154 |     async with _guided_conversation.engine(
155 |         definition=step_context.config.definition,
156 |         artifact_type=artifact_type,
157 |         state_file_path=_get_guided_conversation_state_file_path(step_context.context),
158 |         openai_client=step_context.llm_config.openai_client_factory(),
159 |         openai_model=step_context.llm_config.openai_model,
160 |         context=step_context.context,
161 |         state_id=_guided_conversation_inspector.state_id,
162 |     ) as gce:
163 |         try:
164 |             result = await gce.step_conversation(message)
165 |         except Exception as e:
166 |             logger.exception("failed to execute guided conversation")
167 |             return IncompleteErrorResult(
168 |                 message=f"Failed to execute guided conversation: {e}",
169 |                 debug={"error": str(e)},
170 |             )
171 | 
172 |         debug["guided-conversation"] = gce.to_json()
173 | 
174 |         logger.info("guided-conversation result: %s", result)
175 | 
176 |         fill_form_gc_artifact = gce.artifact.artifact.model_dump(mode="json")
177 |         logger.info("guided-conversation artifact: %s", gce.artifact)
178 | 
179 |     populated_form_markdown = _generate_populated_form(
180 |         form=form,
181 |         populated_fields=fill_form_gc_artifact,
182 |     )
183 | 
184 |     async with step_state(step_context.context) as current_state:
185 |         current_state.populated_form_markdown = populated_form_markdown
186 | 
187 |         if result.is_conversation_over:
188 |             return CompleteResult(
189 |                 message=current_state.populated_form_markdown,
190 |                 artifact=fill_form_gc_artifact,
191 |                 populated_form_markdown=current_state.populated_form_markdown,
192 |                 debug=debug,
193 |             )
194 | 
195 |         return IncompleteResult(message=result.ai_message or "", debug=debug)
196 | 
197 | 
198 | async def _candidate_values_from_attachments_as_message_part(
199 |     step_context: Context[FillFormConfig], form_filename: str, form_fields: list[state.FormField]
200 | ) -> tuple[str, dict[str, Any]]:
201 |     """Extract candidate values from the attachments, using chat-completion, and return them as a message part."""
202 | 
203 |     debug_per_file = {}
204 |     attachment_candidate_value_parts = []
205 |     async with step_context.context.set_status("inspecting attachments ..."):
206 |         async for attachment in step_context.latest_user_input.attachments:
207 |             if attachment.filename == form_filename:
208 |                 continue
209 | 
210 |             candidate_values, metadata = await _extract_field_candidates(
211 |                 llm_config=step_context.llm_config,
212 |                 config=step_context.config.extract_config,
213 |                 form_fields=form_fields,
214 |                 document_content=attachment.content,
215 |             )
216 | 
217 |             message_part = _candidate_values_to_message_part(attachment.filename, candidate_values)
218 |             attachment_candidate_value_parts.append(message_part)
219 | 
220 |             debug_per_file[attachment.filename] = metadata
221 | 
222 |     return "\n".join(attachment_candidate_value_parts), debug_per_file
223 | 
224 | 
225 | def _candidate_values_to_message_part(filename: str, candidate_values: FieldValueCandidates) -> str:
226 |     """Build a message part from the candidate values extracted from a document."""
227 |     header = dedent(f"""===
228 |         Filename: *{filename}*
229 |         {candidate_values.response}
230 |     """)
231 | 
232 |     fields = []
233 |     for candidate in candidate_values.fields:
234 |         fields.append(
235 |             dedent(f"""
236 |             Field id: {candidate.field_id}:
237 |                 Value: {candidate.value}
238 |                 Explanation: {candidate.explanation}""")
239 |         )
240 | 
241 |     return "\n".join((header, *fields))
242 | 
243 | 
244 | def _form_fields_to_artifact_basemodel(form_fields: list[state.FormField]):
245 |     """Create a BaseModel for the filled-form-artifact based on the form fields."""
246 |     field_definitions: dict[str, tuple[Any, Any]] = {}
247 |     required_fields = []
248 |     for field in form_fields:
249 |         if field.required:
250 |             required_fields.append(field.id)
251 | 
252 |         match field.type:
253 |             case state.FieldType.text | state.FieldType.signature | state.FieldType.date:
254 |                 field_type = str
255 | 
256 |             case state.FieldType.text_list:
257 |                 field_type = list[str]
258 | 
259 |             case state.FieldType.currency:
260 |                 field_type = float
261 | 
262 |             case state.FieldType.multiple_choice:
263 |                 match field.option_selections_allowed:
264 |                     case state.AllowedOptionSelections.one:
265 |                         field_type = Literal[tuple(field.options)]
266 | 
267 |                     case state.AllowedOptionSelections.many:
268 |                         field_type = list[Literal[tuple(field.options)]]
269 | 
270 |                     case _:
271 |                         raise ValueError(f"Unsupported option_selections_allowed: {field.option_selections_allowed}")
272 | 
273 |             case _:
274 |                 raise ValueError(f"Unsupported field type: {field.type}")
275 | 
276 |         if not field.required:
277 |             field_type = Optional[field_type]
278 | 
279 |         field_definitions[field.id] = (field_type, Field(title=field.name, description=field.description))
280 | 
281 |     return create_model(
282 |         "FilledFormArtifact",
283 |         __config__=ConfigDict(json_schema_extra={"required": required_fields}),
284 |         **field_definitions,  # type: ignore
285 |     )
286 | 
287 | 
288 | def _get_guided_conversation_state_file_path(context: ConversationContext) -> Path:
289 |     return _guided_conversation.path_for_state(context, "fill_form")
290 | 
291 | 
292 | _guided_conversation_inspector = FileStateInspector(
293 |     display_name="Debug: Fill-Form Guided-Conversation",
294 |     file_path_source=_get_guided_conversation_state_file_path,
295 | )
296 | 
297 | 
298 | def _get_step_state_file_path(context: ConversationContext) -> Path:
299 |     return storage_directory_for_context(context, "fill_form_state.json")
300 | 
301 | 
302 | def project_populated_form(state: dict) -> str:
303 |     return state.get("populated_form_markdown") or ""
304 | 
305 | 
306 | _populated_form_state_inspector = FileStateInspector(
307 |     display_name="Populated Form",
308 |     file_path_source=_get_step_state_file_path,
309 |     projector=project_populated_form,
310 | )
311 | 
312 | 
313 | async def _extract_field_candidates(
314 |     llm_config: LLMConfig,
315 |     config: ExtractCandidateFieldValuesConfig,
316 |     form_fields: list[state.FormField],
317 |     document_content: str,
318 | ) -> tuple[FieldValueCandidates, dict[str, Any]]:
319 |     class _SerializationModel(BaseModel):
320 |         fields: list[state.FormField]
321 | 
322 |     messages: list[ChatCompletionMessageParam] = [
323 |         {
324 |             "role": "system",
325 |             "content": config.instruction.replace(
326 |                 "{{form_fields}}", _SerializationModel(fields=form_fields).model_dump_json(indent=4)
327 |             ),
328 |         },
329 |         {
330 |             "role": "user",
331 |             "content": document_content,
332 |         },
333 |     ]
334 | 
335 |     return await _llm.structured_completion(
336 |         llm_config=llm_config,
337 |         messages=messages,
338 |         response_model=FieldValueCandidates,
339 |     )
340 | 
341 | 
342 | def _generate_populated_form(
343 |     form: state.Form,
344 |     populated_fields: dict,
345 | ) -> str:
346 |     def field_value(field_id: str) -> str | list[str]:
347 |         value = populated_fields.get(field_id) or ""
348 |         if value == "Unanswered":
349 |             return ""
350 |         if value == "null":
351 |             return ""
352 |         if isinstance(value, list):
353 |             return value
354 |         return value
355 | 
356 |     def field_values(fields: list[state.FormField]) -> str:
357 |         markdown_fields: list[str] = []
358 | 
359 |         for field in fields:
360 |             value = field_value(field.id)
361 | 
362 |             markdown_fields.append("_" * 20)
363 |             markdown_fields.append(f"{field.name}:")
364 |             if field.description:
365 |                 markdown_fields.append(f'<span style="font-size: 0.75em;opacity:0.6;">ℹ️ {field.description}</span>\n')
366 | 
367 |             match field.type:
368 |                 case (
369 |                     state.FieldType.text
370 |                     | state.FieldType.signature
371 |                     | state.FieldType.date
372 |                     | state.FieldType.text_list
373 |                     | state.FieldType.currency
374 |                 ):
375 |                     match value:
376 |                         case str():
377 |                             markdown_fields.append(value)
378 | 
379 |                         case int() | float():
380 |                             markdown_fields.append(str(value))
381 | 
382 |                         case list():
383 |                             for item in value:
384 |                                 markdown_fields.append(f"- {item}")
385 | 
386 |                 case state.FieldType.multiple_choice:
387 |                     for option in field.options:
388 |                         if option == value:
389 |                             markdown_fields.append(f"- [x] {option}\n")
390 |                             continue
391 |                         markdown_fields.append(f"- [ ] {option}\n")
392 | 
393 |                 case _:
394 |                     raise ValueError(f"Unsupported field type: {field.type}")
395 | 
396 |         return "\n\n".join(markdown_fields)
397 | 
398 |     def for_section(level: int, section: state.Section) -> str:
399 |         sections = (for_section(level + 1, section) for section in section.sections)
400 |         return "\n".join((
401 |             f"{'#' * level} {section.title}",
402 |             section.description,
403 |             section.instructions,
404 |             field_values(section.fields),
405 |             *sections,
406 |         ))
407 | 
408 |     return "\n".join((
409 |         "```markdown",
410 |         for_section(1, form),
411 |         "```",
412 |     ))
413 | 
414 | 
415 | @asynccontextmanager
416 | async def step_state(context: ConversationContext) -> AsyncIterator[FillFormState]:
417 |     state_file_path = _get_step_state_file_path(context)
418 |     step_state = state.read_model(state_file_path, FillFormState) or FillFormState()
419 |     async with context.state_updated_event_after(_populated_form_state_inspector.state_id, focus_event=True):
420 |         yield step_state
421 |         state.write_model(state_file_path, step_state)
422 | 
```

--------------------------------------------------------------------------------
/libraries/python/assistant-extensions/assistant_extensions/attachments/_attachments.py:
--------------------------------------------------------------------------------

```python
  1 | import asyncio
  2 | import contextlib
  3 | import io
  4 | import logging
  5 | from typing import Any, Awaitable, Callable, Sequence
  6 | 
  7 | import openai_client
  8 | from assistant_drive import IfDriveFileExistsBehavior
  9 | from llm_client.model import CompletionMessage, CompletionMessageImageContent, CompletionMessageTextContent
 10 | from semantic_workbench_api_model.workbench_model import (
 11 |     ConversationEvent,
 12 |     File,
 13 |     MessageType,
 14 |     NewConversationMessage,
 15 | )
 16 | from semantic_workbench_assistant.assistant_app import (
 17 |     AssistantAppProtocol,
 18 |     AssistantCapability,
 19 |     ConversationContext,
 20 | )
 21 | 
 22 | from . import _convert as convert
 23 | from ._model import Attachment, AttachmentsConfigModel, AttachmentSummary, Summarizer
 24 | from ._shared import (
 25 |     attachment_drive_for_context,
 26 |     attachment_to_original_filename,
 27 |     original_to_attachment_filename,
 28 |     summary_drive_for_context,
 29 | )
 30 | from ._summarizer import get_attachment_summary, summarize_attachment_task
 31 | 
 32 | logger = logging.getLogger(__name__)
 33 | 
 34 | 
 35 | AttachmentProcessingErrorHandler = Callable[[ConversationContext, str, Exception], Awaitable]
 36 | 
 37 | 
 38 | async def log_and_send_message_on_error(context: ConversationContext, filename: str, e: Exception) -> None:
 39 |     """
 40 |     Default error handler for attachment processing, which logs the exception and sends
 41 |     a message to the conversation.
 42 |     """
 43 | 
 44 |     logger.exception("exception occurred processing attachment", exc_info=e)
 45 |     await context.send_messages(
 46 |         NewConversationMessage(
 47 |             content=f"There was an error processing the attachment ({filename}): {e}",
 48 |             message_type=MessageType.notice,
 49 |             metadata={"attribution": "system"},
 50 |         )
 51 |     )
 52 | 
 53 | 
 54 | attachment_tag = "ATTACHMENT"
 55 | filename_tag = "FILENAME"
 56 | content_tag = "CONTENT"
 57 | error_tag = "ERROR"
 58 | image_tag = "IMAGE"
 59 | 
 60 | 
 61 | class AttachmentsExtension:
 62 |     def __init__(
 63 |         self,
 64 |         assistant: AssistantAppProtocol,
 65 |         error_handler: AttachmentProcessingErrorHandler = log_and_send_message_on_error,
 66 |     ) -> None:
 67 |         """
 68 |         AttachmentsExtension produces chat completion messages for the files in a conversation. These
 69 |         messages include the text representations of the files ("attachments"), and their filenames.
 70 |         These messages can be included in chat-completion API calls, providing context to the LLM about
 71 |         the files in the conversation.
 72 | 
 73 |         Args:
 74 |             assistant: The assistant app to bind to.
 75 |             error_handler: The error handler to be notified when errors occur while extracting attachments
 76 |             from files.
 77 | 
 78 |         Example:
 79 |             ```python
 80 |             from assistant_extensions.attachments import AttachmentsExtension
 81 | 
 82 |             assistant = AssistantApp(...)
 83 | 
 84 |             attachments_extension = AttachmentsExtension(assistant)
 85 | 
 86 | 
 87 |             @assistant.events.conversation.message.chat.on_created
 88 |             async def on_message_created(
 89 |                 context: ConversationContext, event: ConversationEvent, message: ConversationMessage
 90 |             ) -> None:
 91 |                 ...
 92 |                 config = ...
 93 |                 completion_messages = await attachments_extension.get_completion_messages_for_attachments(
 94 |                     context,
 95 |                     config,
 96 |                 )
 97 |             ```
 98 |         """
 99 | 
100 |         self._error_handler = error_handler
101 | 
102 |         # add the 'supports_conversation_files' capability to the assistant, to indicate that this
103 |         # assistant supports files in the conversation
104 |         assistant.add_capability(AssistantCapability.supports_conversation_files)
105 | 
106 |         # listen for file events for to pro-actively update and delete attachments
107 | 
108 |         @assistant.events.conversation.file.on_deleted_including_mine
109 |         async def on_file_deleted(context: ConversationContext, event: ConversationEvent, file: File) -> None:
110 |             """
111 |             Delete an attachment when a file is deleted in the conversation.
112 |             """
113 | 
114 |             # delete the attachment for the file
115 |             await _delete_attachment_for_file(context, file)
116 | 
117 |     async def get_completion_messages_for_attachments(
118 |         self,
119 |         context: ConversationContext,
120 |         config: AttachmentsConfigModel,
121 |         include_filenames: list[str] = [],
122 |         exclude_filenames: list[str] = [],
123 |         summarizer: Summarizer | None = None,
124 |     ) -> Sequence[CompletionMessage]:
125 |         """
126 |         Generate user messages for each attachment that includes the filename and content.
127 | 
128 |         In the case of images, the content will be a data URI, other file types will be included as text.
129 | 
130 |         Args:
131 |             context: The conversation context.
132 |             config: The configuration for the attachment agent.
133 |             include_filenames: The filenames of the attachments to include.
134 |             exclude_filenames: The filenames of the attachments to exclude. If provided, this will take precedence over include_filenames.
135 | 
136 |         Returns:
137 |             A list of messages for the chat completion.
138 |         """
139 | 
140 |         # get attachments, filtered by include_filenames and exclude_filenames
141 |         attachments = await get_attachments(
142 |             context,
143 |             error_handler=self._error_handler,
144 |             include_filenames=include_filenames,
145 |             exclude_filenames=exclude_filenames,
146 |             summarizer=summarizer,
147 |         )
148 | 
149 |         if not attachments:
150 |             return []
151 | 
152 |         messages: list[CompletionMessage] = [_create_message(config.preferred_message_role, config.context_description)]
153 | 
154 |         # process each attachment
155 |         for attachment in attachments:
156 |             messages.append(_create_message_for_attachment(config.preferred_message_role, attachment))
157 | 
158 |         return messages
159 | 
160 |     async def get_attachment_filenames(
161 |         self,
162 |         context: ConversationContext,
163 |         include_filenames: list[str] = [],
164 |         exclude_filenames: list[str] = [],
165 |     ) -> list[str]:
166 |         files_response = await context.list_files()
167 | 
168 |         # for all files, get the attachment
169 |         for file in files_response.files:
170 |             if include_filenames and file.filename not in include_filenames:
171 |                 continue
172 |             if file.filename in exclude_filenames:
173 |                 continue
174 | 
175 |         # delete cached attachments that are no longer in the conversation
176 |         filenames = list({file.filename for file in files_response.files})
177 | 
178 |         return filenames
179 | 
180 | 
181 | def _create_message_for_attachment(preferred_message_role: str, attachment: Attachment) -> CompletionMessage:
182 |     # if the content is a data URI, include it as an image type within the message content
183 |     if attachment.content.startswith("data:image/"):
184 |         return CompletionMessage(
185 |             role="user",
186 |             content=[
187 |                 CompletionMessageTextContent(
188 |                     type="text",
189 |                     text=f"<{attachment_tag}><{filename_tag}>{attachment.filename}</{filename_tag}><{image_tag}>",
190 |                 ),
191 |                 CompletionMessageImageContent(
192 |                     type="image",
193 |                     media_type="image/png",
194 |                     data=attachment.content,
195 |                 ),
196 |                 CompletionMessageTextContent(
197 |                     type="text",
198 |                     text=f"</{image_tag}></{attachment_tag}>",
199 |                 ),
200 |             ],
201 |         )
202 | 
203 |     error_element = f"<{error_tag}>{attachment.error}</{error_tag}>" if attachment.error else ""
204 |     content = f"<{attachment_tag}><{filename_tag}>{attachment.filename}</{filename_tag}>{error_element}<{content_tag}>{attachment.content}</{content_tag}></{attachment_tag}>"
205 |     return _create_message(preferred_message_role, content)
206 | 
207 | 
208 | def _create_message(preferred_message_role: str, content: str) -> CompletionMessage:
209 |     match preferred_message_role:
210 |         case "system":
211 |             return CompletionMessage(
212 |                 role="system",
213 |                 content=content,
214 |             )
215 |         case "user":
216 |             return CompletionMessage(
217 |                 role="user",
218 |                 content=content,
219 |             )
220 |         case _:
221 |             raise ValueError(f"unsupported preferred_message_role: {preferred_message_role}")
222 | 
223 | 
224 | async def default_error_handler(context: ConversationContext, filename: str, e: Exception) -> None:
225 |     logger.exception("error reading file %s", filename, exc_info=e)
226 | 
227 | 
228 | async def get_attachments(
229 |     context: ConversationContext,
230 |     exclude_filenames: list[str] = [],
231 |     include_filenames: list[str] = [],
232 |     error_handler: AttachmentProcessingErrorHandler = default_error_handler,
233 |     summarizer: Summarizer | None = None,
234 | ) -> list[Attachment]:
235 |     """
236 |     Gets all attachments for the current state of the conversation, updating the cache as needed.
237 |     """
238 | 
239 |     # get all files in the conversation
240 |     files_response = await context.list_files()
241 | 
242 |     # delete cached attachments that are no longer in the conversation
243 |     filenames = {file.filename for file in files_response.files}
244 |     asyncio.create_task(_delete_attachments_not_in(context, filenames))
245 | 
246 |     attachments = []
247 |     # for all files, get the attachment
248 |     for file in files_response.files:
249 |         if include_filenames and file.filename not in include_filenames:
250 |             continue
251 |         if file.filename in exclude_filenames:
252 |             continue
253 | 
254 |         attachment = await _get_attachment_for_file(context, file, {}, error_handler, summarizer=summarizer)
255 |         attachments.append(attachment)
256 | 
257 |     return attachments
258 | 
259 | 
260 | async def _delete_attachments_not_in(context: ConversationContext, filenames: set[str]) -> None:
261 |     """Deletes cached attachments that are not in the filenames argument."""
262 |     drive = attachment_drive_for_context(context)
263 |     summary_drive = summary_drive_for_context(context)
264 |     for attachment_filename in drive.list():
265 |         if attachment_filename == "summaries":
266 |             continue
267 | 
268 |         original_file_name = attachment_to_original_filename(attachment_filename)
269 |         if original_file_name in filenames:
270 |             continue
271 | 
272 |         with contextlib.suppress(FileNotFoundError):
273 |             drive.delete(attachment_filename)
274 | 
275 |         with contextlib.suppress(FileNotFoundError):
276 |             summary_drive.delete(attachment_filename)
277 | 
278 |         await _delete_lock_for_context_file(context, original_file_name)
279 | 
280 | 
281 | _file_locks_lock = asyncio.Lock()
282 | _file_locks: dict[str, asyncio.Lock] = {}
283 | 
284 | 
285 | async def _delete_lock_for_context_file(context: ConversationContext, filename: str) -> None:
286 |     async with _file_locks_lock:
287 |         key = f"{context.assistant.id}/{context.id}/{filename}"
288 |         if key not in _file_locks:
289 |             return
290 | 
291 |         del _file_locks[key]
292 | 
293 | 
294 | async def _lock_for_context_file(context: ConversationContext, filename: str) -> asyncio.Lock:
295 |     """
296 |     Get a lock for the given file in the given context.
297 |     """
298 |     async with _file_locks_lock:
299 |         key = f"{context.assistant.id}/{context.id}/{filename}"
300 |         if key not in _file_locks:
301 |             _file_locks[key] = asyncio.Lock()
302 | 
303 |         return _file_locks[key]
304 | 
305 | 
306 | async def _get_attachment_for_file(
307 |     context: ConversationContext,
308 |     file: File,
309 |     metadata: dict[str, Any],
310 |     error_handler: AttachmentProcessingErrorHandler,
311 |     summarizer: Summarizer | None = None,
312 | ) -> Attachment:
313 |     """
314 |     Get the attachment for the file. If the attachment is not cached, or the file is
315 |     newer than the cached attachment, the text content of the file will be extracted
316 |     and the cache will be updated.
317 |     """
318 | 
319 |     # ensure that only one async task is updating the attachment for the file
320 |     file_lock = await _lock_for_context_file(context, file.filename)
321 |     async with file_lock:
322 |         attachment = await _get_or_update_attachment(
323 |             context=context,
324 |             file=file,
325 |             metadata=metadata,
326 |             error_handler=error_handler,
327 |         )
328 | 
329 |         summary = AttachmentSummary(summary="")
330 |         if summarizer:
331 |             summary = await _get_or_update_attachment_summary(
332 |                 context=context,
333 |                 attachment=attachment,
334 |                 summarizer=summarizer,
335 |             )
336 | 
337 |     return attachment.model_copy(update={"summary": summary})
338 | 
339 | 
340 | async def _get_or_update_attachment(
341 |     context: ConversationContext, file: File, metadata: dict[str, Any], error_handler: AttachmentProcessingErrorHandler
342 | ) -> Attachment:
343 |     drive = attachment_drive_for_context(context)
344 | 
345 |     with contextlib.suppress(FileNotFoundError):
346 |         attachment = drive.read_model(Attachment, original_to_attachment_filename(file.filename))
347 | 
348 |         if attachment.updated_datetime.timestamp() >= file.updated_datetime.timestamp():
349 |             # if the attachment is up-to-date, return it
350 |             return attachment
351 | 
352 |     content = ""
353 |     error = ""
354 |     # process the file to create an attachment
355 |     async with context.set_status(f"updating attachment {file.filename}..."):
356 |         try:
357 |             # read the content of the file
358 |             file_bytes = await _read_conversation_file(context, file)
359 |             # convert the content of the file to a string
360 |             content = await convert.bytes_to_str(file_bytes, filename=file.filename)
361 |         except Exception as e:
362 |             await error_handler(context, file.filename, e)
363 |             error = f"error processing file: {e}"
364 | 
365 |     attachment = Attachment(
366 |         filename=file.filename,
367 |         content=content,
368 |         metadata=metadata,
369 |         updated_datetime=file.updated_datetime,
370 |         error=error,
371 |     )
372 |     drive.write_model(
373 |         attachment, original_to_attachment_filename(file.filename), if_exists=IfDriveFileExistsBehavior.OVERWRITE
374 |     )
375 | 
376 |     completion_message = _create_message_for_attachment(preferred_message_role="system", attachment=attachment)
377 |     openai_completion_messages = openai_client.messages.convert_from_completion_messages([completion_message])
378 |     token_count = openai_client.num_tokens_from_message(openai_completion_messages[0], model="gpt-4o")
379 | 
380 |     # update the conversation token count based on the token count of the latest version of this file
381 |     prior_token_count = file.metadata.get("token_count", 0)
382 |     conversation = await context.get_conversation()
383 |     token_counts = conversation.metadata.get("token_counts", {})
384 |     if token_counts:
385 |         total = token_counts.get("total", 0)
386 |         total += token_count - prior_token_count
387 |         await context.update_conversation({
388 |             "token_counts": {
389 |                 **token_counts,
390 |                 "total": total,
391 |             },
392 |         })
393 | 
394 |     await context.update_file(
395 |         file.filename,
396 |         metadata={
397 |             "token_count": token_count,
398 |         },
399 |     )
400 | 
401 |     return attachment
402 | 
403 | 
404 | async def _get_or_update_attachment_summary(
405 |     context: ConversationContext, attachment: Attachment, summarizer: Summarizer
406 | ) -> AttachmentSummary:
407 |     attachment_summary = await get_attachment_summary(
408 |         context=context,
409 |         filename=attachment.filename,
410 |     )
411 |     if attachment_summary.updated_datetime.timestamp() < attachment.updated_datetime.timestamp():
412 |         # if the summary is not up-to-date, schedule a task to update it
413 |         asyncio.create_task(
414 |             summarize_attachment_task(
415 |                 context=context,
416 |                 summarizer=summarizer,
417 |                 attachment=attachment,
418 |             )
419 |         )
420 | 
421 |     return attachment_summary
422 | 
423 | 
424 | async def _delete_attachment_for_file(context: ConversationContext, file: File) -> None:
425 |     drive = attachment_drive_for_context(context)
426 | 
427 |     with contextlib.suppress(FileNotFoundError):
428 |         drive.delete(file.filename)
429 | 
430 |     summary_drive = summary_drive_for_context(context)
431 |     with contextlib.suppress(FileNotFoundError):
432 |         summary_drive.delete(file.filename)
433 | 
434 |     await _delete_lock_for_context_file(context, file.filename)
435 | 
436 |     # update the conversation token count based on the token count of the latest version of this file
437 |     file_token_count = file.metadata.get("token_count", 0)
438 |     if not file_token_count:
439 |         return
440 | 
441 |     conversation = await context.get_conversation()
442 |     token_counts = conversation.metadata.get("token_counts", {})
443 |     if not token_counts:
444 |         return
445 | 
446 |     total = token_counts.get("total", 0)
447 |     if not total:
448 |         return
449 | 
450 |     total -= file_token_count
451 | 
452 |     await context.update_conversation({
453 |         "token_counts": {
454 |             **token_counts,
455 |             "total": total,
456 |         },
457 |     })
458 | 
459 | 
460 | async def _read_conversation_file(context: ConversationContext, file: File) -> bytes:
461 |     """
462 |     Read the content of the file with the given filename.
463 |     """
464 |     buffer = io.BytesIO()
465 | 
466 |     async with context.read_file(file.filename) as reader:
467 |         async for chunk in reader:
468 |             buffer.write(chunk)
469 | 
470 |     buffer.seek(0)
471 |     return buffer.read()
472 | 
```

--------------------------------------------------------------------------------
/mcp-servers/ai-assist-content/mcp-python-sdk-README.md:
--------------------------------------------------------------------------------

```markdown
  1 | # MCP Python SDK
  2 | 
  3 | <div align="center">
  4 | 
  5 | <strong>Python implementation of the Model Context Protocol (MCP)</strong>
  6 | 
  7 | [![PyPI][pypi-badge]][pypi-url]
  8 | [![MIT licensed][mit-badge]][mit-url]
  9 | [![Python Version][python-badge]][python-url]
 10 | [![Documentation][docs-badge]][docs-url]
 11 | [![Specification][spec-badge]][spec-url]
 12 | [![GitHub Discussions][discussions-badge]][discussions-url]
 13 | 
 14 | </div>
 15 | 
 16 | <!-- omit in toc -->
 17 | ## Table of Contents
 18 | 
 19 | - [Overview](#overview)
 20 | - [Installation](#installation)
 21 | - [Quickstart](#quickstart)
 22 | - [What is MCP?](#what-is-mcp)
 23 | - [Core Concepts](#core-concepts)
 24 |   - [Server](#server)
 25 |   - [Resources](#resources)
 26 |   - [Tools](#tools)
 27 |   - [Prompts](#prompts)
 28 |   - [Images](#images)
 29 |   - [Context](#context)
 30 | - [Running Your Server](#running-your-server)
 31 |   - [Development Mode](#development-mode)
 32 |   - [Claude Desktop Integration](#claude-desktop-integration)
 33 |   - [Direct Execution](#direct-execution)
 34 | - [Examples](#examples)
 35 |   - [Echo Server](#echo-server)
 36 |   - [SQLite Explorer](#sqlite-explorer)
 37 | - [Advanced Usage](#advanced-usage)
 38 |   - [Low-Level Server](#low-level-server)
 39 |   - [Writing MCP Clients](#writing-mcp-clients)
 40 |   - [MCP Primitives](#mcp-primitives)
 41 |   - [Server Capabilities](#server-capabilities)
 42 | - [Documentation](#documentation)
 43 | - [Contributing](#contributing)
 44 | - [License](#license)
 45 | 
 46 | [pypi-badge]: https://img.shields.io/pypi/v/mcp.svg
 47 | [pypi-url]: https://pypi.org/project/mcp/
 48 | [mit-badge]: https://img.shields.io/pypi/l/mcp.svg
 49 | [mit-url]: https://github.com/modelcontextprotocol/python-sdk/blob/main/LICENSE
 50 | [python-badge]: https://img.shields.io/pypi/pyversions/mcp.svg
 51 | [python-url]: https://www.python.org/downloads/
 52 | [docs-badge]: https://img.shields.io/badge/docs-modelcontextprotocol.io-blue.svg
 53 | [docs-url]: https://modelcontextprotocol.io
 54 | [spec-badge]: https://img.shields.io/badge/spec-spec.modelcontextprotocol.io-blue.svg
 55 | [spec-url]: https://spec.modelcontextprotocol.io
 56 | [discussions-badge]: https://img.shields.io/github/discussions/modelcontextprotocol/python-sdk
 57 | [discussions-url]: https://github.com/modelcontextprotocol/python-sdk/discussions
 58 | 
 59 | ## Overview
 60 | 
 61 | The Model Context Protocol allows applications to provide context for LLMs in a standardized way, separating the concerns of providing context from the actual LLM interaction. This Python SDK implements the full MCP specification, making it easy to:
 62 | 
 63 | - Build MCP clients that can connect to any MCP server
 64 | - Create MCP servers that expose resources, prompts and tools
 65 | - Use standard transports like stdio and SSE
 66 | - Handle all MCP protocol messages and lifecycle events
 67 | 
 68 | ## Installation
 69 | 
 70 | We recommend using [uv](https://docs.astral.sh/uv/) to manage your Python projects:
 71 | 
 72 | ```bash
 73 | uv add "mcp[cli]"
 74 | ```
 75 | 
 76 | Alternatively:
 77 | ```bash
 78 | pip install mcp
 79 | ```
 80 | 
 81 | ## Quickstart
 82 | 
 83 | Let's create a simple MCP server that exposes a calculator tool and some data:
 84 | 
 85 | ```python
 86 | # server.py
 87 | from mcp.server.fastmcp import FastMCP
 88 | 
 89 | # Create an MCP server
 90 | mcp = FastMCP("Demo")
 91 | 
 92 | # Add an addition tool
 93 | @mcp.tool()
 94 | def add(a: int, b: int) -> int:
 95 |     """Add two numbers"""
 96 |     return a + b
 97 | 
 98 | # Add a dynamic greeting resource
 99 | @mcp.resource("greeting://{name}")
100 | def get_greeting(name: str) -> str:
101 |     """Get a personalized greeting"""
102 |     return f"Hello, {name}!"
103 | ```
104 | 
105 | You can install this server in [Claude Desktop](https://claude.ai/download) and interact with it right away by running:
106 | ```bash
107 | mcp install server.py
108 | ```
109 | 
110 | Alternatively, you can test it with the MCP Inspector:
111 | ```bash
112 | mcp dev server.py
113 | ```
114 | 
115 | ## What is MCP?
116 | 
117 | The [Model Context Protocol (MCP)](https://modelcontextprotocol.io) lets you build servers that expose data and functionality to LLM applications in a secure, standardized way. Think of it like a web API, but specifically designed for LLM interactions. MCP servers can:
118 | 
119 | - Expose data through **Resources** (think of these sort of like GET endpoints; they are used to load information into the LLM's context)
120 | - Provide functionality through **Tools** (sort of like POST endpoints; they are used to execute code or otherwise produce a side effect)
121 | - Define interaction patterns through **Prompts** (reusable templates for LLM interactions)
122 | - And more!
123 | 
124 | ## Core Concepts
125 | 
126 | ### Server
127 | 
128 | The FastMCP server is your core interface to the MCP protocol. It handles connection management, protocol compliance, and message routing:
129 | 
130 | ```python
131 | # Add lifespan support for startup/shutdown with strong typing
132 | from dataclasses import dataclass
133 | from typing import AsyncIterator
134 | from mcp.server.fastmcp import FastMCP
135 | 
136 | # Create a named server
137 | mcp = FastMCP("My App")
138 | 
139 | # Specify dependencies for deployment and development
140 | mcp = FastMCP("My App", dependencies=["pandas", "numpy"])
141 | 
142 | @dataclass
143 | class AppContext:
144 |     db: Database  # Replace with your actual DB type
145 | 
146 | @asynccontextmanager
147 | async def app_lifespan(server: FastMCP) -> AsyncIterator[AppContext]:
148 |     """Manage application lifecycle with type-safe context"""
149 |     try:
150 |         # Initialize on startup
151 |         await db.connect()
152 |         yield AppContext(db=db)
153 |     finally:
154 |         # Cleanup on shutdown
155 |         await db.disconnect()
156 | 
157 | # Pass lifespan to server
158 | mcp = FastMCP("My App", lifespan=app_lifespan)
159 | 
160 | # Access type-safe lifespan context in tools
161 | @mcp.tool()
162 | def query_db(ctx: Context) -> str:
163 |     """Tool that uses initialized resources"""
164 |     db = ctx.request_context.lifespan_context["db"]
165 |     return db.query()
166 | ```
167 | 
168 | ### Resources
169 | 
170 | Resources are how you expose data to LLMs. They're similar to GET endpoints in a REST API - they provide data but shouldn't perform significant computation or have side effects:
171 | 
172 | ```python
173 | @mcp.resource("config://app")
174 | def get_config() -> str:
175 |     """Static configuration data"""
176 |     return "App configuration here"
177 | 
178 | @mcp.resource("users://{user_id}/profile")
179 | def get_user_profile(user_id: str) -> str:
180 |     """Dynamic user data"""
181 |     return f"Profile data for user {user_id}"
182 | ```
183 | 
184 | ### Tools
185 | 
186 | Tools let LLMs take actions through your server. Unlike resources, tools are expected to perform computation and have side effects:
187 | 
188 | ```python
189 | @mcp.tool()
190 | def calculate_bmi(weight_kg: float, height_m: float) -> float:
191 |     """Calculate BMI given weight in kg and height in meters"""
192 |     return weight_kg / (height_m ** 2)
193 | 
194 | @mcp.tool()
195 | async def fetch_weather(city: str) -> str:
196 |     """Fetch current weather for a city"""
197 |     async with httpx.AsyncClient() as client:
198 |         response = await client.get(f"https://api.weather.com/{city}")
199 |         return response.text
200 | ```
201 | 
202 | ### Prompts
203 | 
204 | Prompts are reusable templates that help LLMs interact with your server effectively:
205 | 
206 | ```python
207 | @mcp.prompt()
208 | def review_code(code: str) -> str:
209 |     return f"Please review this code:\n\n{code}"
210 | 
211 | @mcp.prompt()
212 | def debug_error(error: str) -> list[Message]:
213 |     return [
214 |         UserMessage("I'm seeing this error:"),
215 |         UserMessage(error),
216 |         AssistantMessage("I'll help debug that. What have you tried so far?")
217 |     ]
218 | ```
219 | 
220 | ### Images
221 | 
222 | FastMCP provides an `Image` class that automatically handles image data:
223 | 
224 | ```python
225 | from mcp.server.fastmcp import FastMCP, Image
226 | from PIL import Image as PILImage
227 | 
228 | @mcp.tool()
229 | def create_thumbnail(image_path: str) -> Image:
230 |     """Create a thumbnail from an image"""
231 |     img = PILImage.open(image_path)
232 |     img.thumbnail((100, 100))
233 |     return Image(data=img.tobytes(), format="png")
234 | ```
235 | 
236 | ### Context
237 | 
238 | The Context object gives your tools and resources access to MCP capabilities:
239 | 
240 | ```python
241 | from mcp.server.fastmcp import FastMCP, Context
242 | 
243 | @mcp.tool()
244 | async def long_task(files: list[str], ctx: Context) -> str:
245 |     """Process multiple files with progress tracking"""
246 |     for i, file in enumerate(files):
247 |         ctx.info(f"Processing {file}")
248 |         await ctx.report_progress(i, len(files))
249 |         data, mime_type = await ctx.read_resource(f"file://{file}")
250 |     return "Processing complete"
251 | ```
252 | 
253 | ## Running Your Server
254 | 
255 | ### Development Mode
256 | 
257 | The fastest way to test and debug your server is with the MCP Inspector:
258 | 
259 | ```bash
260 | mcp dev server.py
261 | 
262 | # Add dependencies
263 | mcp dev server.py --with pandas --with numpy
264 | 
265 | # Mount local code
266 | mcp dev server.py --with-editable .
267 | ```
268 | 
269 | ### Claude Desktop Integration
270 | 
271 | Once your server is ready, install it in Claude Desktop:
272 | 
273 | ```bash
274 | mcp install server.py
275 | 
276 | # Custom name
277 | mcp install server.py --name "My Analytics Server"
278 | 
279 | # Environment variables
280 | mcp install server.py -v API_KEY=abc123 -v DB_URL=postgres://...
281 | mcp install server.py -f .env
282 | ```
283 | 
284 | ### Direct Execution
285 | 
286 | For advanced scenarios like custom deployments:
287 | 
288 | ```python
289 | from mcp.server.fastmcp import FastMCP
290 | 
291 | mcp = FastMCP("My App")
292 | 
293 | if __name__ == "__main__":
294 |     mcp.run()
295 | ```
296 | 
297 | Run it with:
298 | ```bash
299 | python server.py
300 | # or
301 | mcp run server.py
302 | ```
303 | 
304 | ## Examples
305 | 
306 | ### Echo Server
307 | 
308 | A simple server demonstrating resources, tools, and prompts:
309 | 
310 | ```python
311 | from mcp.server.fastmcp import FastMCP
312 | 
313 | mcp = FastMCP("Echo")
314 | 
315 | @mcp.resource("echo://{message}")
316 | def echo_resource(message: str) -> str:
317 |     """Echo a message as a resource"""
318 |     return f"Resource echo: {message}"
319 | 
320 | @mcp.tool()
321 | def echo_tool(message: str) -> str:
322 |     """Echo a message as a tool"""
323 |     return f"Tool echo: {message}"
324 | 
325 | @mcp.prompt()
326 | def echo_prompt(message: str) -> str:
327 |     """Create an echo prompt"""
328 |     return f"Please process this message: {message}"
329 | ```
330 | 
331 | ### SQLite Explorer
332 | 
333 | A more complex example showing database integration:
334 | 
335 | ```python
336 | from mcp.server.fastmcp import FastMCP
337 | import sqlite3
338 | 
339 | mcp = FastMCP("SQLite Explorer")
340 | 
341 | @mcp.resource("schema://main")
342 | def get_schema() -> str:
343 |     """Provide the database schema as a resource"""
344 |     conn = sqlite3.connect("database.db")
345 |     schema = conn.execute(
346 |         "SELECT sql FROM sqlite_master WHERE type='table'"
347 |     ).fetchall()
348 |     return "\n".join(sql[0] for sql in schema if sql[0])
349 | 
350 | @mcp.tool()
351 | def query_data(sql: str) -> str:
352 |     """Execute SQL queries safely"""
353 |     conn = sqlite3.connect("database.db")
354 |     try:
355 |         result = conn.execute(sql).fetchall()
356 |         return "\n".join(str(row) for row in result)
357 |     except Exception as e:
358 |         return f"Error: {str(e)}"
359 | ```
360 | 
361 | ## Advanced Usage
362 | 
363 | ### Low-Level Server
364 | 
365 | For more control, you can use the low-level server implementation directly. This gives you full access to the protocol and allows you to customize every aspect of your server, including lifecycle management through the lifespan API:
366 | 
367 | ```python
368 | from contextlib import asynccontextmanager
369 | from typing import AsyncIterator
370 | 
371 | @asynccontextmanager
372 | async def server_lifespan(server: Server) -> AsyncIterator[dict]:
373 |     """Manage server startup and shutdown lifecycle."""
374 |     try:
375 |         # Initialize resources on startup
376 |         await db.connect()
377 |         yield {"db": db}
378 |     finally:
379 |         # Clean up on shutdown
380 |         await db.disconnect()
381 | 
382 | # Pass lifespan to server
383 | server = Server("example-server", lifespan=server_lifespan)
384 | 
385 | # Access lifespan context in handlers
386 | @server.call_tool()
387 | async def query_db(name: str, arguments: dict) -> list:
388 |     ctx = server.request_context
389 |     db = ctx.lifespan_context["db"]
390 |     return await db.query(arguments["query"])
391 | ```
392 | 
393 | The lifespan API provides:
394 | - A way to initialize resources when the server starts and clean them up when it stops
395 | - Access to initialized resources through the request context in handlers
396 | - Type-safe context passing between lifespan and request handlers
397 | 
398 | ```python
399 | from mcp.server.lowlevel import Server, NotificationOptions
400 | from mcp.server.models import InitializationOptions
401 | import mcp.server.stdio
402 | import mcp.types as types
403 | 
404 | # Create a server instance
405 | server = Server("example-server")
406 | 
407 | @server.list_prompts()
408 | async def handle_list_prompts() -> list[types.Prompt]:
409 |     return [
410 |         types.Prompt(
411 |             name="example-prompt",
412 |             description="An example prompt template",
413 |             arguments=[
414 |                 types.PromptArgument(
415 |                     name="arg1",
416 |                     description="Example argument",
417 |                     required=True
418 |                 )
419 |             ]
420 |         )
421 |     ]
422 | 
423 | @server.get_prompt()
424 | async def handle_get_prompt(
425 |     name: str,
426 |     arguments: dict[str, str] | None
427 | ) -> types.GetPromptResult:
428 |     if name != "example-prompt":
429 |         raise ValueError(f"Unknown prompt: {name}")
430 | 
431 |     return types.GetPromptResult(
432 |         description="Example prompt",
433 |         messages=[
434 |             types.PromptMessage(
435 |                 role="user",
436 |                 content=types.TextContent(
437 |                     type="text",
438 |                     text="Example prompt text"
439 |                 )
440 |             )
441 |         ]
442 |     )
443 | 
444 | async def run():
445 |     async with mcp.server.stdio.stdio_server() as (read_stream, write_stream):
446 |         await server.run(
447 |             read_stream,
448 |             write_stream,
449 |             InitializationOptions(
450 |                 server_name="example",
451 |                 server_version="0.1.0",
452 |                 capabilities=server.get_capabilities(
453 |                     notification_options=NotificationOptions(),
454 |                     experimental_capabilities={},
455 |                 )
456 |             )
457 |         )
458 | 
459 | if __name__ == "__main__":
460 |     import asyncio
461 |     asyncio.run(run())
462 | ```
463 | 
464 | ### Writing MCP Clients
465 | 
466 | The SDK provides a high-level client interface for connecting to MCP servers:
467 | 
468 | ```python
469 | from mcp import ClientSession, StdioServerParameters
470 | from mcp.client.stdio import stdio_client
471 | 
472 | # Create server parameters for stdio connection
473 | server_params = StdioServerParameters(
474 |     command="python", # Executable
475 |     args=["example_server.py"], # Optional command line arguments
476 |     env=None # Optional environment variables
477 | )
478 | 
479 | # Optional: create a sampling callback
480 | async def handle_sampling_message(message: types.CreateMessageRequestParams) -> types.CreateMessageResult:
481 |     return types.CreateMessageResult(
482 |         role="assistant",
483 |         content=types.TextContent(
484 |             type="text",
485 |             text="Hello, world! from model",
486 |         ),
487 |         model="gpt-3.5-turbo",
488 |         stopReason="endTurn",
489 |     )
490 | 
491 | async def run():
492 |     async with stdio_client(server_params) as (read, write):
493 |         async with ClientSession(read, write, sampling_callback=handle_sampling_message) as session:
494 |             # Initialize the connection
495 |             await session.initialize()
496 | 
497 |             # List available prompts
498 |             prompts = await session.list_prompts()
499 | 
500 |             # Get a prompt
501 |             prompt = await session.get_prompt("example-prompt", arguments={"arg1": "value"})
502 | 
503 |             # List available resources
504 |             resources = await session.list_resources()
505 | 
506 |             # List available tools
507 |             tools = await session.list_tools()
508 | 
509 |             # Read a resource
510 |             content, mime_type = await session.read_resource("file://some/path")
511 | 
512 |             # Call a tool
513 |             result = await session.call_tool("tool-name", arguments={"arg1": "value"})
514 | 
515 | if __name__ == "__main__":
516 |     import asyncio
517 |     asyncio.run(run())
518 | ```
519 | 
520 | ### MCP Primitives
521 | 
522 | The MCP protocol defines three core primitives that servers can implement:
523 | 
524 | | Primitive | Control               | Description                                         | Example Use                  |
525 | |-----------|-----------------------|-----------------------------------------------------|------------------------------|
526 | | Prompts   | User-controlled       | Interactive templates invoked by user choice        | Slash commands, menu options |
527 | | Resources | Application-controlled| Contextual data managed by the client application   | File contents, API responses |
528 | | Tools     | Model-controlled      | Functions exposed to the LLM to take actions        | API calls, data updates      |
529 | 
530 | ### Server Capabilities
531 | 
532 | MCP servers declare capabilities during initialization:
533 | 
534 | | Capability  | Feature Flag                 | Description                        |
535 | |-------------|------------------------------|------------------------------------|
536 | | `prompts`   | `listChanged`                | Prompt template management         |
537 | | `resources` | `subscribe`<br/>`listChanged`| Resource exposure and updates      |
538 | | `tools`     | `listChanged`                | Tool discovery and execution       |
539 | | `logging`   | -                            | Server logging configuration       |
540 | | `completion`| -                            | Argument completion suggestions    |
541 | 
542 | ## Documentation
543 | 
544 | - [Model Context Protocol documentation](https://modelcontextprotocol.io)
545 | - [Model Context Protocol specification](https://spec.modelcontextprotocol.io)
546 | - [Officially supported servers](https://github.com/modelcontextprotocol/servers)
547 | 
548 | ## Contributing
549 | 
550 | We are passionate about supporting contributors of all levels of experience and would love to see you get involved in the project. See the [contributing guide](CONTRIBUTING.md) to get started.
551 | 
552 | ## License
553 | 
554 | This project is licensed under the MIT License - see the LICENSE file for details.
555 | 
```
Page 88/145FirstPrevNextLast