diff --git a/README.md b/README.md index a28723e..6f47a9b 100644 --- a/README.md +++ b/README.md @@ -1,97 +1,80 @@ # πŸ€– Microbots -MicroBots is a lightweight, extensible AI agent for code comprehension and controlled file edits. It integrates cleanly -into automation pipelines, mounting a target directory with explicit read-only or read/write modes so LLMs can safely -inspect, refactor, or generate files with least‑privilege access. +MicroBots is a lightweight, extensible AI agent for code comprehension and controlled file edits. It integrates cleanly into automation pipelines, mounting a target directory with explicit read-only or read/write modes so LLMs can safely inspect, refactor, or generate files with least-privilege access. - -```py -from microbots import WritingBot - -myWritingBot = WritingBot( - model="azure-openai/my-gpt5", # model format : - folder_to_mount=str("myReactApp"), -) - -data = myWritingBot.run("""when doing npm run build, I get an error. -Fix the error and make sure the build is successful.""", timeout_in_seconds=600) -print(data.results) -``` - -## πŸš€ How to install +## πŸš€ Quick Start ### Pre-requisites - Docker - AI LLM Provider and API Key -### Install Microbots +### Install ```bash pip install microbots ``` +### Example -## ✨LLM Support +```python +from microbots import WritingBot -Azure OpenAI Models - Add the below environment variables in a `.env` file in the root of your application +myWritingBot = WritingBot( + model="azure-openai/my-gpt5", + folder_to_mount=str("myReactApp"), +) -```env -AZURE_OPENAI_ENDPOINT=XXXXXXXXXXXXXXXXXXXXXXXXXX -AZURE_OPENAI_API_KEY=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -AZURE_OPENAI_API_VERSION=2025-03-01-preview +data = myWritingBot.run( + "Fix the build error and make sure the build is successful.", + timeout_in_seconds=600, +) +print(data.results) ``` -## πŸ€– Bots & Usage Examples - -Pre-requisite for the below example code of Bots: -From the root of your application, Create a folder called `code` inside which clone the repo `https://github.com/swe-agent/test-repo/`. Now run the code - - -### πŸ“– ReadingBot - - -```py -from microbots import ReadingBot - -myBot = ReadingBot( - model="azure-openai/my-gpt5", - folder_to_mount="code" -) +## πŸ€– Available Bots -runResult = myBot.run("When I am running missing_colon.py I am getting SyntaxError: invalid syntax. Find the error and explain me what is the error", timeout_in_seconds=600) -print(runResult) +| Bot | Description | +| ------------------ | ---------------------------------------------------------------------- | +| **ReadingBot** | Reads files and extracts information based on instructions (read-only) | +| **WritingBot** | Reads and writes files based on instructions (read/write) | +| **BrowsingBot** | Browses the web to gather information | +| **LogAnalysisBot** | Analyzes logs for debugging | +| **AgentBoss** | Orchestrates multiple bots for complex tasks | -``` +## βš™οΈ How it works -The `ReadingBot` will read the files inside `code` folder and will extract information based on specific instructions given to the bot. +![Overall Architecture](https://raw.githubusercontent.com/microsoft/microbots/main/docs/images/overall_architecture.png) +MicroBots creates a containerized environment and mounts the specified directory, restricting permissions to read-only or read/write based on the Bot used. This ensures AI agents operate within defined boundaries, enhancing security and control over code modifications while protecting the local environment. -### ✍️ WritingBot +## ✨ LLM Support -Pre-requisite for the example code: -From the root the application, Create a folder called `code` inside which clone the repo `https://github.com/swe-agent/test-repo/`. Now run the code +Microbots supports multiple LLM providers β€” pick whichever fits your stack: -```py -from microbots import WritingBot +| Provider string | Description | +| --------------- | ---------------------------------------------------------- | +| `openai` | OpenAI or Azure OpenAI via the OpenAI SDK (API key) | +| `azure-openai` | Azure OpenAI via the Azure SDK (API key or Azure AD token) | +| `anthropic` | Anthropic models, direct or via Azure AI Foundry | +| `ollama-local` | Local models via [Ollama](https://ollama.com/) | -myBot = WritingBot( - model="azure-openai/my-gpt5", - folder_to_mount="code" -) +Each provider has its own set of environment variables (endpoint, API key, deployment name, etc.). See the [Authentication guide](https://microsoft.github.io/microbots/advanced/authentication/) for the exact `.env` variables required for each provider and for Azure AD / managed identity setup. -myBot.run("When I am running missing_colon.py I am getting SyntaxError: invalid syntax. Fix the error and make sure the code runs without any errors.", timeout_in_seconds=600) -``` +## πŸ“š Links -The `WritingBot` will read and write the files inside `code` folder based on specific instructions given to the bot. +- [GitHub Repository](https://github.com/microsoft/microbots) +- [Contributing Guide](https://github.com/microsoft/microbots/blob/main/CONTRIBUTING.md) +- [Code of Conduct](https://github.com/microsoft/microbots/blob/main/CODE_OF_CONDUCT.md) -## βš™οΈ How it works +--- +## 🎯 Getting Started -![Overall Architecture Image](./docs/images/overall_architecture.png) +Ready to build your first Microbot project? Follow the step-by-step onboarding guide: -The MicroBots create a containerized environment and mount the specified directory with restricting the permissions to read-only or read/write based on Bot used. It ensures that the AI agents operate within defined boundaries which enhances security and control over code modifications as well as protecting the local environment. +➑️ **[Get Started with Microbots](https://microsoft.github.io/microbots/getting-started/prerequisites/)** -#Legal Notice +## Legal Notice -Trademarks This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft’s Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party’s policies. \ No newline at end of file +Trademarks: this project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies. diff --git a/docs/guides/assets/azure-managed-identity-setup/mi-01-create-form.png b/docs/advanced/assets/azure-managed-identity-setup/mi-01-create-form.png similarity index 100% rename from docs/guides/assets/azure-managed-identity-setup/mi-01-create-form.png rename to docs/advanced/assets/azure-managed-identity-setup/mi-01-create-form.png diff --git a/docs/guides/assets/azure-managed-identity-setup/mi-02-overview.png b/docs/advanced/assets/azure-managed-identity-setup/mi-02-overview.png similarity index 100% rename from docs/guides/assets/azure-managed-identity-setup/mi-02-overview.png rename to docs/advanced/assets/azure-managed-identity-setup/mi-02-overview.png diff --git a/docs/guides/assets/azure-managed-identity-setup/sc-01-new-arm.png b/docs/advanced/assets/azure-managed-identity-setup/sc-01-new-arm.png similarity index 100% rename from docs/guides/assets/azure-managed-identity-setup/sc-01-new-arm.png rename to docs/advanced/assets/azure-managed-identity-setup/sc-01-new-arm.png diff --git a/docs/guides/assets/azure-managed-identity-setup/sc-02-managed-identity-form.png b/docs/advanced/assets/azure-managed-identity-setup/sc-02-managed-identity-form.png similarity index 100% rename from docs/guides/assets/azure-managed-identity-setup/sc-02-managed-identity-form.png rename to docs/advanced/assets/azure-managed-identity-setup/sc-02-managed-identity-form.png diff --git a/docs/authentication.md b/docs/advanced/authentication.md similarity index 100% rename from docs/authentication.md rename to docs/advanced/authentication.md diff --git a/docs/guides/azure-managed-identity-setup.md b/docs/advanced/azure-managed-identity-setup.md similarity index 99% rename from docs/guides/azure-managed-identity-setup.md rename to docs/advanced/azure-managed-identity-setup.md index 40e29c3..f56d85b 100644 --- a/docs/guides/azure-managed-identity-setup.md +++ b/docs/advanced/azure-managed-identity-setup.md @@ -259,5 +259,5 @@ One identity, one service connection, many Microbots pipelines. ## Next Steps - **Conceptual background** β†’ [Understanding RBAC & Authentication](../blog/rbac-authentication.md) -- **All authentication options** β†’ [Authentication Setup](../authentication.md) +- **All authentication options** β†’ [Authentication Setup](authentication.md) - **Why secret-less matters** β†’ [Microbots: Safety First Agentic Workflow](../blog/microbots-safety-first-ai-agent.md) diff --git a/docs/copilot-bot.md b/docs/advanced/bots/copilot-bot.md similarity index 100% rename from docs/copilot-bot.md rename to docs/advanced/bots/copilot-bot.md diff --git a/docs/advanced/technical-writing-guidelines.md b/docs/advanced/technical-writing-guidelines.md new file mode 100644 index 0000000..d092bfb --- /dev/null +++ b/docs/advanced/technical-writing-guidelines.md @@ -0,0 +1,384 @@ +# Technical Writing Guidelines + +This guide defines the writing standards for all Microbots documentation β€” tutorials, guides, API references, and blog posts. Following these guidelines ensures that every article is consistent in quality, tone, and structure. + +*This guide is inspired by and adapted from [DigitalOcean's Technical Writing Guidelines](https://www.digitalocean.com/community/tutorials/digitalocean-s-technical-writing-guidelines), licensed under [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/).* + +There are four sections in this guide: + +- **Style**, our high-level approach to writing technical content +- **Structure**, an explanation of our layout and content expectations +- **Formatting**, a Markdown reference for MkDocs Material +- **Terminology**, a guide to common terms and word usage + +Read the **Style** and **Structure** sections in their entirety before you begin writing. Use the **Formatting** and **Terminology** sections as references while drafting. + +--- + +## Style + +Microbots documentation is written for developers and engineers who want to learn, build, and automate with confidence. Every article should be: + +- Comprehensive and written for all experience levels +- Technically detailed and correct +- Practical, useful, and self-contained +- Friendly but formal + +### Comprehensive and Written for All Experience Levels + +Articles should be as clear and detailed as possible without making assumptions about the reader's background knowledge. + +Explicitly include every command a reader needs β€” from creating a virtual environment to the final working setup. Provide all explanations and background information the reader needs to understand the tutorial. The goal is for readers to **learn the concepts**, not just copy and paste code. + +**Avoid** words like "simple," "straightforward," "easy," "simply," "obviously," and "just." These words make assumptions about the reader's knowledge. A reader who hears something is "easy" may be frustrated when they encounter an issue. Instead, encourage readers by providing the explanations they need to be successful. + +### Technically Detailed and Correct + +Articles must be technically accurate and follow industry best practices. Do not provide large blocks of configuration or code and ask readers to paste it, trusting that it works and is safe. Provide all the details necessary for readers to understand and trust the article. + +- Every command should have a detailed explanation, including options and flags as necessary. +- Every block of code should be followed by prose that describes what it does and why it works that way. +- When you ask the reader to execute a command or modify a file, first explain what it does and why. + +**Authors must test their tutorials** by following them exactly as written on a fresh environment to ensure accuracy and identify missing steps. + +### Practical, Useful, and Self-contained + +Once a reader has finished an article, they should have installed, built, or set up something from start to finish. Emphasize a practical approach β€” at the end of an article, the reader should have a usable environment or example to build upon. + +- Link to existing Microbots documentation as prerequisites that readers should complete before beginning the tutorial. +- Link to other Microbots articles for additional information within the body of the tutorial. +- Only send readers to external sites when there is no existing Microbots article and the information cannot be summarized inline. + +### Friendly but Formal + +Articles aim for a friendly but formal tone. This means articles do not include jargon, memes, excessive slang, emoji, or jokes. We write for a global audience, so aim for a tone that works across language and cultural boundaries. + +- **Do not** use the first person singular (e.g., "I think …"). +- **Use** the second person (e.g., "You will configure …") to keep the focus on the reader and what they will accomplish. +- In some cases, use the first person plural (e.g., "We will examine …"). + +Use motivational language focused on outcomes. For example, instead of "You will learn how to install Microbots," write "In this tutorial, you will install Microbots and create your first bot." This approach motivates the reader and focuses on the goal. + +--- + +## Structure + +Microbots articles have a consistent structure that includes an introduction, prerequisites, and a conclusion. The specific structure depends on the type of article. + +### Procedural Tutorials (Step-by-step) + +``` +# Title (H1) +### Introduction (H3) +## Prerequisites (H2) +## Step 1 β€” Doing the First Thing (H2) +## Step 2 β€” Doing the Next Thing (H2) +… +## Step n β€” Doing the Last Thing (H2) +## Conclusion (H2) +``` + +### Conceptual Articles + +``` +# Title (H1) +### Introduction (H3) +## Prerequisites (optional) (H2) +## Subtopic 1 (H2) +## Subtopic 2 (H2) +… +## Subtopic n (H2) +## Conclusion (H2) +``` + +### Title + +Think carefully about what the reader will accomplish by following your tutorial. Include the **goal** of the tutorial in the title, not just the tools involved. Keep titles under 60 characters when possible. + +**Good:** "Microbots : Introduction, Installation Guide and Creating Your First MicroBot" + +The title should communicate both the tool and the outcome. + +### Introduction + +The introduction is typically one to three paragraphs. Its purpose is to motivate the reader, set expectations, and summarize what they will do. Answer these questions: + +1. **What** is the tutorial about? What software is involved? +2. **Why** should the reader learn this? What are the practical benefits? +3. **What will the reader do** in this tutorial? Be specific. +4. **What will the reader have accomplished** when finished? What new skills will they have? + +Keep the focus on the reader. Use "you will configure" rather than "we will learn how to." + +### Prerequisites + +The Prerequisites section spells out exactly what the reader should have or do before starting. Format it as a **checklist** the reader can follow: + +```markdown +## Prerequisites + +To complete this tutorial, you will need: + +- **Python 3.10+** installed on your machine. See the [Pre-requisites](../getting-started/prerequisites.md) guide. +- **Docker** installed and running. See the [Pre-requisites](../getting-started/prerequisites.md#docker) guide. +- A working **Azure OpenAI** API key, endpoint, and deployed model. See the [Project Setup and Microbots Installation](../getting-started/project-setup-and-installation.md) guide. +``` + +Each prerequisite must link to an existing Microbots article or official documentation. Be specific β€” "Familiarity with Python" is not actionable; instead write "Familiarity with Python virtual environments. See [Python venv documentation](https://docs.python.org/3/library/venv.html)." + +### Steps + +Steps are the core of your tutorial. Each step: + +- Begins with a **level 2 heading** in the format: `## Step N β€” Gerund Phrase` +- Starts with an introductory sentence describing what the reader will do and why +- Contains commands, code listings, files, and explanations + +**Example:** + +```markdown +## Step 1 β€” Setting Up the Project Directory + +In this step, you will create a project folder and initialize a Python virtual environment. This isolates your dependencies from the system Python installation. +``` + +### Transitions + +Each step should end with a brief closing sentence that: + +1. Summarizes what the reader accomplished +2. Introduces what they will do next + +**Example:** + +> You have now installed the Microbots package and configured your LLM credentials. In the next step, you will create a sample project with a deliberate error for the bot to analyze. + +Vary the language so transitions do not feel repetitive. + +### Conclusion + +The conclusion summarizes what the reader accomplished. Use "you configured" or "you built" rather than "we learned how to." + +Include: + +- A brief recap of what was accomplished +- Suggestions for what the reader can do next +- Links to related Microbots tutorials or API references +- Links to external resources where appropriate + +--- + +## Formatting + +Microbots documentation is written in Markdown and rendered with MkDocs Material. Follow these formatting conventions. + +### Headers + +| Level | Usage | +| ----------- | --------------------------------------------------------------- | +| H1 (`#`) | Title only β€” one per article | +| H2 (`##`) | Major sections: Introduction, Prerequisites, Steps, Conclusion | +| H3 (`###`) | Subsections within a step or section | +| H4 (`####`) | Use sparingly; prefer restructuring into multiple steps instead | + +For procedural tutorials, step headers should include step numbers followed by an em dash (β€”) and use the gerund (-ing form): + +```markdown +## Step 1 β€” Installing Microbots +``` + +### Line-level Formatting + +**Bold** text should be used for: + +- Visible GUI text +- Hostnames and usernames +- Term lists +- Emphasis when changing context (e.g., switching to a different terminal) + +*Italics* should only be used when introducing technical terms. For example: *The Microbots framework uses OverlayFS for copy-on-write filesystem protection.* + +`Inline code` formatting should be used for: + +- Command names, like `pip` +- Package names, like `microbots` +- File names and paths, like `~/.env` +- Example URLs, like `https://your-resource-name.openai.azure.com` +- Ports, like `:8000` +- Key presses, in ALL CAPS, like `ENTER`. For simultaneous keys, use `CTRL+C` + +### Code Blocks + +Code blocks should be used for: + +- Commands the reader needs to execute +- Files and scripts +- Terminal output +- Interactive dialogues + +Always include a **title** on code blocks using the `title` attribute: + +````markdown +```bash title="Terminal" +pip install microbots +``` +```` + +For file contents, use the filename as the title: + +````markdown +```python title="log_analysis_bot.py" linenums="1" +from microbots import LogAnalysisBot +``` +```` + +#### Explaining Commands + +Every command should be preceded by a description of what it does. After the command, provide additional details about arguments and flags: + +````markdown +Execute the following command to create a Python virtual environment: + +```bash title="Terminal" +python -m venv .venv +``` + +The `-m venv` flag tells Python to run the `venv` module, which creates an isolated virtual environment in the `.venv` directory. +```` + +#### Showing Output + +Separate command output from the command itself using a distinct code block with an explanatory sentence: + +````markdown +Run the bot: + +```bash title="Terminal" +python log_analysis_bot.py +``` + +The program's output will print to the screen: + +```text title="Output" +Root cause identified from /var/log/build.log: ... +``` +```` + +#### Highlighting Changes + +When modifying an existing file, show the relevant section and explain what changed and why. Use comments or callouts to draw attention to the specific lines. + +### Admonitions + +Use MkDocs Material admonitions for notes, warnings, and tips: + +```markdown +!!! note + For advanced authentication options, see the Authentication Guide. + +!!! warning + This action will delete all data in the container. + +!!! tip + You can use `logging.basicConfig(level=logging.INFO)` to see step-by-step bot output. +``` + +Use them sparingly. Reserve `warning` for actions that could cause data loss or security issues. Use `tip` for helpful but optional information. + +### Images + +When including images: + +- Use descriptive alt text for screen reader accessibility +- Use the `.png` file format +- Place images in the `docs/images/` directory under a subfolder named after the article +- Keep image height as short as possible + +```markdown +![Architecture diagram showing Docker container isolation](../images/microbots-safety-first-ai-agent/architecture.png) +``` + +### Navigation Cards + +Use navigation cards (rather than plain-text links) for Previous/Next links. Place the **Previous** card at the top of the article and the **Next** card at the bottom: + +```html + + + + + +``` + +For articles that have prerequisites the reader should complete first, add prerequisite cards at the top alongside the Previous card: + +```html + +``` + +--- + +## Terminology + +### Users and Variables + +- Use `your-resource-name` as the default placeholder for Azure resource names. +- Use `your-api-key-here` as the default placeholder for API keys. +- Always highlight variables that readers need to change. + +### Bot Names + +Use the official class name with proper capitalization: + +| Correct | Incorrect | +| ---------------- | -------------------------------- | +| `LogAnalysisBot` | Log Analysis Bot, loganalysisbot | +| `ReadingBot` | Reading Bot, readingbot | +| `WritingBot` | Writing Bot, writingbot | +| `BrowsingBot` | Browsing Bot, browsingbot | +| `AgentBoss` | Agent Boss, agentboss | +| `CopilotBot` | Copilot Bot, copilotbot | + +### LLM Providers + +Use the provider/model format when referencing models: + +- `azure-openai/gpt-5-swe-agent` +- `anthropic/claude-sonnet-4-20250514` +- `ollama/llama3` + +### Permission Labels + +Use ALL CAPS for permission labels: `READ_ONLY`, `READ_WRITE`. + +### Software and Tools + +- Use the official capitalization from the project's website: **Docker**, **Python**, **MkDocs**, **TypeScript**. +- Link to the software's home page the first time it is mentioned. + +### Technical Best Practices + +- Always test tutorials on a fresh environment before submitting. +- Use the `--8<--` snippet syntax for including example files rather than duplicating code. +- Keep code examples minimal and focused on the concept being taught. +- Ensure all external links are valid at the time of writing and add the External Links Disclaimer admonition when external links are present. diff --git a/docs/blog/guides/tesseract_ocr_tool_use.md b/docs/advanced/tools/tesseract_ocr_tool_use.md similarity index 100% rename from docs/blog/guides/tesseract_ocr_tool_use.md rename to docs/advanced/tools/tesseract_ocr_tool_use.md diff --git a/docs/blog/microbots-customizability.md b/docs/blog/microbots-customizability.md index 55da047..a551074 100644 --- a/docs/blog/microbots-customizability.md +++ b/docs/blog/microbots-customizability.md @@ -59,7 +59,7 @@ uninstall_commands: No Python code. No changes to MicroBot. Tools can be `internal` (runs inside the Docker sandbox) or `external` (runs on the host β€” useful for sub-agents or host-side logic). > **Want to build one end-to-end?** -> Walk through [Custom Tool Integration: Tesseract OCR](../blog/guides/tesseract_ocr_tool_use.md) β€” it builds a production-ready OCR tool from scratch and uses it to extract form fields from scanned documents. +> Walk through [Custom Tool Integration: Tesseract OCR](../advanced/tools/tesseract_ocr_tool_use.md) β€” it builds a production-ready OCR tool from scratch and uses it to extract form fields from scanned documents. --- diff --git a/docs/blog/rbac-authentication.md b/docs/blog/rbac-authentication.md index 8c0dadb..ecaa20c 100644 --- a/docs/blog/rbac-authentication.md +++ b/docs/blog/rbac-authentication.md @@ -2,7 +2,7 @@ Microbots supports both API Key and Azure AD authentication for LLM providers. This guide breaks down how each method works, what Azure RBAC is, and which one to use for your setup. -For setup instructions, see the [Authentication setup guide](../authentication.md). +For setup instructions, see the [Authentication setup guide](../advanced/authentication.md). --- @@ -166,6 +166,6 @@ az role assignment create \ ## Next Steps -- **Set up API Key auth** β†’ [Authentication Guide: API Key](../authentication.md#1-api-key-authentication-default) -- **Set up Azure AD auth** β†’ [Authentication Guide: Azure AD](../authentication.md#2-azure-ad-token-authentication) +- **Set up API Key auth** β†’ [Authentication Guide: API Key](../advanced/authentication.md#1-api-key-authentication-default) +- **Set up Azure AD auth** β†’ [Authentication Guide: Azure AD](../advanced/authentication.md#2-azure-ad-token-authentication) - **Understand the safety model** β†’ [Safety-First Agentic Workflow](../blog/microbots-safety-first-ai-agent.md) diff --git a/docs/examples/microbots_introduction/code/app.c b/docs/examples/microbots_introduction/code/app.c new file mode 100644 index 0000000..faa0945 --- /dev/null +++ b/docs/examples/microbots_introduction/code/app.c @@ -0,0 +1,12 @@ +// app.c β€” A simple greeting program with a syntax error +#include + +int add(int a, int b) { + return a + b +} + +int main(void) { + printf("Hello, Microbots!\n"); + printf("2 + 3 = %d\n", add(2, 3)); + return 0; +} diff --git a/docs/examples/microbots_introduction/log_analysis_bot.py b/docs/examples/microbots_introduction/log_analysis_bot.py new file mode 100644 index 0000000..db610dc --- /dev/null +++ b/docs/examples/microbots_introduction/log_analysis_bot.py @@ -0,0 +1,16 @@ +import logging + +logging.basicConfig(level=logging.INFO) + +from microbots import LogAnalysisBot + +my_bot = LogAnalysisBot( + model="azure-openai/gpt-5-agent", + folder_to_mount="code", +) + +result = my_bot.run( + file_name="code/build.log", + timeout_in_seconds=600, +) +print(result.result) diff --git a/docs/examples/microbots_introduction/log_analysis_logger_debug.txt b/docs/examples/microbots_introduction/log_analysis_logger_debug.txt new file mode 100644 index 0000000..8c87f6d --- /dev/null +++ b/docs/examples/microbots_introduction/log_analysis_logger_debug.txt @@ -0,0 +1,358 @@ +(.venv) sikannan@sikannan-ubuntu-vm:~/codeBase/microbots-introduction$ python3 log_analysis_bot.py +DEBUG:docker.utils.config:Trying paths: ['/home/sikannan/.docker/config.json', '/home/sikannan/.dockercfg'] +DEBUG:docker.utils.config:No config file found +DEBUG:docker.utils.config:Trying paths: ['/home/sikannan/.docker/config.json', '/home/sikannan/.dockercfg'] +DEBUG:docker.utils.config:No config file found +DEBUG:urllib3.connectionpool:http://localhost:None "GET /version HTTP/1.1" 200 891 +INFO:microbots.environment.local_docker.LocalDockerEnvironment:πŸ—‚οΈ Created working directory at /home/sikannan/MICROBOTS_WORKDIR_79b91420 +INFO:microbots.environment.local_docker.LocalDockerEnvironment:πŸ“¦ Volume mapping: /home/sikannan/codeBase/microbots-introduction/code β†’ /ro/code +DEBUG:urllib3.connectionpool:http://localhost:None "POST /v1.54/containers/create HTTP/1.1" 201 88 +DEBUG:urllib3.connectionpool:http://localhost:None "GET /v1.54/containers/5f1012fd83ae4a70bc9c7223afe67345c4bb467557ae711794e26217fd23fdbf/json HTTP/1.1" 200 None +DEBUG:urllib3.connectionpool:http://localhost:None "POST /v1.54/containers/5f1012fd83ae4a70bc9c7223afe67345c4bb467557ae711794e26217fd23fdbf/start HTTP/1.1" 204 0 +INFO:microbots.environment.local_docker.LocalDockerEnvironment:πŸš€ Started container 5f1012fd83ae with image kavyasree261002/shell_server:latest on host port 58241 +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:➑️ Executing command in container: mkdir -p //workdir/code //workdir/overlay/code/upper //workdir/overlay/code/work && sleep 5 && mount -t overlay overlay -o lowerdir=/ro/code/,upperdir=/workdir/overlay/code/upper/,workdir=/workdir/overlay/code/work/ //workdir/code +DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): localhost:58241 +DEBUG:urllib3.connectionpool:http://localhost:58241 "POST / HTTP/1.1" 200 71 +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:Command completed in 5.02s +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:⬅️ Return Code: 0, +Stdout: + +Stderr: + +INFO:microbots.environment.local_docker.LocalDockerEnvironment:πŸ”’ Set up overlay mount for read-only directory at /workdir/code +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:➑️ Executing command in container: cd //workdir/code +DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): localhost:58241 +DEBUG:urllib3.connectionpool:http://localhost:58241 "POST / HTTP/1.1" 200 71 +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:Command completed in 0.00s +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:⬅️ Return Code: 0, +Stdout: + +Stderr: + +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:➑️ Executing command in container: test -d /var +DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): localhost:58241 +DEBUG:urllib3.connectionpool:http://localhost:58241 "POST / HTTP/1.1" 200 71 +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:Command completed in 0.00s +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:⬅️ Return Code: 0, +Stdout: + +Stderr: + +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:βœ… Destination directory already exists: /var +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:πŸ“ Copying /home/sikannan/codeBase/microbots-introduction/code/build.log to container:/var/log +INFO:microbots.environment.local_docker.LocalDockerEnvironment:βœ… Successfully copied /home/sikannan/codeBase/microbots-introduction/code/build.log to container:/var/log +DEBUG:openai._base_client:Request options: {'method': 'post', 'url': '/responses', 'files': None, 'idempotency_key': 'stainless-python-retry-91b2c538-f866-4600-9e07-c773117d1a68', 'json_data': {'input': [{'role': 'system', 'content': '\n \nYou are a helpful agent well versed in software development and debugging.\n\nYou will be provided with a coding or debugging task to complete inside a sandboxed shell environment.\nThere is a shell session open for you.\nYou will be provided with a task and you should achieve it using the shell commands.\nAll your response must be in the following json format:\n\n{\n "task_done": , // Indicates if the task is completed\n "thoughts": , // The reasoning behind the decision\n "command": // The command to be executed\n}\n\nThe properties ( task_done, thoughts, command ) are mandatory on each response.\nGive the command one at a time to solve the given task. As long as you\'re not done with the task, set task_done to false.\nWhen you are sure that the task is completed, set task_done to true, set command to empty string and provide your final thoughts in the thoughts field.\nDon\'t add any chat or extra messages outside the json format. Because the system will parse only the json response.\nAny of your thoughts must be in the \'thoughts\' field.\n\nafter each command, the system will execute the command and respond to you with the output.\nEnsure to run only one command at a time.\nNEVER use commands that produce large amounts of output or take a long time to run to avoid exceeding context limits.\nUse specific patterns: \'find -name "*.c" -maxdepth 2\' instead of recursive exploration.\nNo human is involved in the task. So, don\'t seek human intervention.\n\nRemember following important points\n1. If a command fails, analyze the error message and provide an alternative command in your next response. Same command will not pass again.\n2. Avoid using recursive commands like \'ls -R\', \'rm -rf\', \'tree\', or \'find\' without depth limits as they can produce excessive output or be destructive.\n3. You cannot run any interactive commands like vim, nano, etc.\n\n You are a helpful log analysis bot. Your job is to analyze a log file and identify the root-cause if there are any failure. You\'ll be given read-only access to the code from where the log is generated. The read-only code is available at //workdir/code.\n\nThe log file to analyze will be given in the user prompt. You can find the provided log file under the directory //var/log/\n\nOnly when you have run all necessary commands and identified the root cause, you should give me the final result.\n '}, {'role': 'user', 'content': '\n Analyze the log file `/var/log`\n '}], 'model': 'gpt-5-swe-agent'}} +DEBUG:openai._base_client:Sending HTTP Request: POST https://azlinux-chatbot-2025.openai.azure.com/openai/v1/responses +DEBUG:httpcore.connection:connect_tcp.started host='azlinux-chatbot-2025.openai.azure.com' port=443 local_address=None timeout=5.0 socket_options=None +DEBUG:httpcore.connection:connect_tcp.complete return_value= +DEBUG:httpcore.connection:start_tls.started ssl_context= server_hostname='azlinux-chatbot-2025.openai.azure.com' timeout=5.0 +DEBUG:httpcore.connection:start_tls.complete return_value= +DEBUG:httpcore.http11:send_request_headers.started request= +DEBUG:httpcore.http11:send_request_headers.complete +DEBUG:httpcore.http11:send_request_body.started request= +DEBUG:httpcore.http11:send_request_body.complete +DEBUG:httpcore.http11:receive_response_headers.started request= +DEBUG:httpcore.http11:receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Content-Length', b'3415'), (b'Content-Type', b'application/json'), (b'skip-error-remapping', b'true'), (b'x-ms-is-spilled-over', b'false'), (b'x-ratelimit-key', b'gpt-5-swe-agent'), (b'x-ratelimit-remaining-requests', b'1499'), (b'x-ratelimit-reset-requests', b'0'), (b'x-ratelimit-limit-requests', b'1500'), (b'x-ratelimit-renewalperiod-requests', b'60'), (b'x-ratelimit-abusepenalty-active', b'False'), (b'x-ratelimit-remaining-tokens', b'149386'), (b'x-ratelimit-reset-tokens', b'0'), (b'x-ratelimit-limit-tokens', b'150000'), (b'x-ratelimit-renewalperiod-tokens', b'60'), (b'azureai-fe-is-streaming', b'False'), (b'x-ms-served-model', b'gpt-5-2025-08-07'), (b'x-request-id', b'17fdd67c-a4d6-4ffc-b2a2-3cafe9dae9f0'), (b'apim-request-id', b'6222c014-dd9a-4dcb-89c3-53c29b37af05'), (b'Strict-Transport-Security', b'max-age=31536000; includeSubDomains; preload'), (b'x-ms-client-request-id', b'Not-Set'), (b'x-content-type-options', b'nosniff'), (b'x-ms-region', b'East US 2'), (b'Date', b'Sat, 23 May 2026 03:26:26 GMT')]) +INFO:httpx:HTTP Request: POST https://azlinux-chatbot-2025.openai.azure.com/openai/v1/responses "HTTP/1.1 200 OK" +DEBUG:httpcore.http11:receive_response_body.started request= +DEBUG:httpcore.http11:receive_response_body.complete +DEBUG:httpcore.http11:response_closed.started +DEBUG:httpcore.http11:response_closed.complete +DEBUG:openai._base_client:HTTP Response: POST https://azlinux-chatbot-2025.openai.azure.com/openai/v1/responses "200 OK" Headers({'content-length': '3415', 'content-type': 'application/json', 'skip-error-remapping': 'true', 'x-ms-is-spilled-over': 'false', 'x-ratelimit-key': 'gpt-5-swe-agent', 'x-ratelimit-remaining-requests': '1499', 'x-ratelimit-reset-requests': '0', 'x-ratelimit-limit-requests': '1500', 'x-ratelimit-renewalperiod-requests': '60', 'x-ratelimit-abusepenalty-active': 'False', 'x-ratelimit-remaining-tokens': '149386', 'x-ratelimit-reset-tokens': '0', 'x-ratelimit-limit-tokens': '150000', 'x-ratelimit-renewalperiod-tokens': '60', 'azureai-fe-is-streaming': 'False', 'x-ms-served-model': 'gpt-5-2025-08-07', 'x-request-id': '17fdd67c-a4d6-4ffc-b2a2-3cafe9dae9f0', 'apim-request-id': '6222c014-dd9a-4dcb-89c3-53c29b37af05', 'strict-transport-security': 'max-age=31536000; includeSubDomains; preload', 'x-ms-client-request-id': 'Not-Set', 'x-content-type-options': 'nosniff', 'x-ms-region': 'East US 2', 'date': 'Sat, 23 May 2026 03:26:26 GMT'}) +DEBUG:openai._base_client:request_id: 17fdd67c-a4d6-4ffc-b2a2-3cafe9dae9f0 +INFO:microbots.llm.llm:The llm response is {'task_done': False, 'thoughts': 'First, I need to see what files exist under /var/log to identify the target log file(s) for analysis.', 'command': 'ls -1 /var/log'} +INFO: MicroBot : ℹ️ TASK STARTED : + Analyze the log file `/var/log` + ... +INFO: MicroBot :-------------------- Step-1 -------------------- +INFO: MicroBot : πŸ’­ LLM thoughts: First, I need to see what files exist under /var/log to identify the target log file(s) for analysis. +INFO: MicroBot : ➑️ LLM tool call : "ls -1 /var/log" +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:➑️ Executing command in container: ls -1 /var/log +DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): localhost:58241 +DEBUG:urllib3.connectionpool:http://localhost:58241 "POST / HTTP/1.1" 200 173 +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:Command completed in 0.00s +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:⬅️ Return Code: 0, +Stdout: +ShellCommunicator.log +alternatives.log +apt +btmp +build.log +dpkg.log +fontconfig.log +lastlog +wtmp +Stderr: + +DEBUG: MicroBot : πŸ”§ Command executed. +Return Code: 0 +Stdout: +ShellCommunicator.log +alternatives.log +apt +btmp +build.log +dpkg.log +fontconfig.log +lastlog +wtmp +Stderr: + +INFO: MicroBot : ⬅️ Command output: +ShellCommunicator.log +alternatives.log +apt +btmp +build.log +dpkg.log +fontconfig.log +lastlog +wtmp +DEBUG:openai._base_client:Request options: {'method': 'post', 'url': '/responses', 'files': None, 'idempotency_key': 'stainless-python-retry-91a2e11a-2473-4c30-a50f-fb78fd7fc16d', 'json_data': {'input': [{'role': 'system', 'content': '\n \nYou are a helpful agent well versed in software development and debugging.\n\nYou will be provided with a coding or debugging task to complete inside a sandboxed shell environment.\nThere is a shell session open for you.\nYou will be provided with a task and you should achieve it using the shell commands.\nAll your response must be in the following json format:\n\n{\n "task_done": , // Indicates if the task is completed\n "thoughts": , // The reasoning behind the decision\n "command": // The command to be executed\n}\n\nThe properties ( task_done, thoughts, command ) are mandatory on each response.\nGive the command one at a time to solve the given task. As long as you\'re not done with the task, set task_done to false.\nWhen you are sure that the task is completed, set task_done to true, set command to empty string and provide your final thoughts in the thoughts field.\nDon\'t add any chat or extra messages outside the json format. Because the system will parse only the json response.\nAny of your thoughts must be in the \'thoughts\' field.\n\nafter each command, the system will execute the command and respond to you with the output.\nEnsure to run only one command at a time.\nNEVER use commands that produce large amounts of output or take a long time to run to avoid exceeding context limits.\nUse specific patterns: \'find -name "*.c" -maxdepth 2\' instead of recursive exploration.\nNo human is involved in the task. So, don\'t seek human intervention.\n\nRemember following important points\n1. If a command fails, analyze the error message and provide an alternative command in your next response. Same command will not pass again.\n2. Avoid using recursive commands like \'ls -R\', \'rm -rf\', \'tree\', or \'find\' without depth limits as they can produce excessive output or be destructive.\n3. You cannot run any interactive commands like vim, nano, etc.\n\n You are a helpful log analysis bot. Your job is to analyze a log file and identify the root-cause if there are any failure. You\'ll be given read-only access to the code from where the log is generated. The read-only code is available at //workdir/code.\n\nThe log file to analyze will be given in the user prompt. You can find the provided log file under the directory //var/log/\n\nOnly when you have run all necessary commands and identified the root cause, you should give me the final result.\n '}, {'role': 'user', 'content': '\n Analyze the log file `/var/log`\n '}, {'role': 'assistant', 'content': '{"task_done": false, "thoughts": "First, I need to see what files exist under /var/log to identify the target log file(s) for analysis.", "command": "ls -1 /var/log"}'}, {'role': 'user', 'content': 'ShellCommunicator.log\nalternatives.log\napt\nbtmp\nbuild.log\ndpkg.log\nfontconfig.log\nlastlog\nwtmp'}], 'model': 'gpt-5-swe-agent'}} +DEBUG:openai._base_client:Sending HTTP Request: POST https://azlinux-chatbot-2025.openai.azure.com/openai/v1/responses +DEBUG:httpcore.http11:send_request_headers.started request= +DEBUG:httpcore.http11:send_request_headers.complete +DEBUG:httpcore.http11:send_request_body.started request= +DEBUG:httpcore.http11:send_request_body.complete +DEBUG:httpcore.http11:receive_response_headers.started request= +DEBUG:httpcore.http11:receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Content-Length', b'3537'), (b'Content-Type', b'application/json'), (b'skip-error-remapping', b'true'), (b'x-ms-is-spilled-over', b'false'), (b'x-ratelimit-key', b'gpt-5-swe-agent'), (b'x-ratelimit-remaining-requests', b'1499'), (b'x-ratelimit-reset-requests', b'0'), (b'x-ratelimit-limit-requests', b'1500'), (b'x-ratelimit-renewalperiod-requests', b'60'), (b'x-ratelimit-abusepenalty-active', b'False'), (b'x-ratelimit-remaining-tokens', b'149321'), (b'x-ratelimit-reset-tokens', b'0'), (b'x-ratelimit-limit-tokens', b'150000'), (b'x-ratelimit-renewalperiod-tokens', b'60'), (b'azureai-fe-is-streaming', b'False'), (b'x-ms-served-model', b'gpt-5-2025-08-07'), (b'x-request-id', b'63044a71-3323-4ec0-bf7c-8fdf9e60ca5d'), (b'apim-request-id', b'e7c50855-f77c-47b5-863f-d7e46631161e'), (b'Strict-Transport-Security', b'max-age=31536000; includeSubDomains; preload'), (b'x-ms-client-request-id', b'Not-Set'), (b'x-content-type-options', b'nosniff'), (b'x-ms-region', b'East US 2'), (b'Date', b'Sat, 23 May 2026 03:26:31 GMT')]) +INFO:httpx:HTTP Request: POST https://azlinux-chatbot-2025.openai.azure.com/openai/v1/responses "HTTP/1.1 200 OK" +DEBUG:httpcore.http11:receive_response_body.started request= +DEBUG:httpcore.http11:receive_response_body.complete +DEBUG:httpcore.http11:response_closed.started +DEBUG:httpcore.http11:response_closed.complete +DEBUG:openai._base_client:HTTP Response: POST https://azlinux-chatbot-2025.openai.azure.com/openai/v1/responses "200 OK" Headers({'content-length': '3537', 'content-type': 'application/json', 'skip-error-remapping': 'true', 'x-ms-is-spilled-over': 'false', 'x-ratelimit-key': 'gpt-5-swe-agent', 'x-ratelimit-remaining-requests': '1499', 'x-ratelimit-reset-requests': '0', 'x-ratelimit-limit-requests': '1500', 'x-ratelimit-renewalperiod-requests': '60', 'x-ratelimit-abusepenalty-active': 'False', 'x-ratelimit-remaining-tokens': '149321', 'x-ratelimit-reset-tokens': '0', 'x-ratelimit-limit-tokens': '150000', 'x-ratelimit-renewalperiod-tokens': '60', 'azureai-fe-is-streaming': 'False', 'x-ms-served-model': 'gpt-5-2025-08-07', 'x-request-id': '63044a71-3323-4ec0-bf7c-8fdf9e60ca5d', 'apim-request-id': 'e7c50855-f77c-47b5-863f-d7e46631161e', 'strict-transport-security': 'max-age=31536000; includeSubDomains; preload', 'x-ms-client-request-id': 'Not-Set', 'x-content-type-options': 'nosniff', 'x-ms-region': 'East US 2', 'date': 'Sat, 23 May 2026 03:26:31 GMT'}) +DEBUG:openai._base_client:request_id: 63044a71-3323-4ec0-bf7c-8fdf9e60ca5d +INFO:microbots.llm.llm:The llm response is {'task_done': False, 'thoughts': "Identify which log contains failures. Start with build.log as it's commonly used for build errors, but first check its length to avoid dumping huge content.", 'command': "wc -l /var/log/build.log 2>/dev/null || echo 'no build.log or not regular file'"} +INFO: MicroBot :-------------------- Step-2 -------------------- +INFO: MicroBot : πŸ’­ LLM thoughts: Identify which log contains failures. Start with build.log as it's commonly used for build errors, but first check its length to avoid dumping huge content. +INFO: MicroBot : ➑️ LLM tool call : "wc -l /var/log/build.log 2>/dev/null || echo 'no build.log or not regular file'" +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:➑️ Executing command in container: wc -l /var/log/build.log 2>/dev/null || echo 'no build.log or not regular file' +DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): localhost:58241 +DEBUG:urllib3.connectionpool:http://localhost:58241 "POST / HTTP/1.1" 200 91 +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:Command completed in 0.01s +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:⬅️ Return Code: 0, +Stdout: +7 /var/log/build.log +Stderr: + +DEBUG: MicroBot : πŸ”§ Command executed. +Return Code: 0 +Stdout: +7 /var/log/build.log +Stderr: + +INFO: MicroBot : ⬅️ Command output: +7 /var/log/build.log +DEBUG:openai._base_client:Request options: {'method': 'post', 'url': '/responses', 'files': None, 'idempotency_key': 'stainless-python-retry-365359aa-20c2-4775-9641-cc2c5607398b', 'json_data': {'input': [{'role': 'system', 'content': '\n \nYou are a helpful agent well versed in software development and debugging.\n\nYou will be provided with a coding or debugging task to complete inside a sandboxed shell environment.\nThere is a shell session open for you.\nYou will be provided with a task and you should achieve it using the shell commands.\nAll your response must be in the following json format:\n\n{\n "task_done": , // Indicates if the task is completed\n "thoughts": , // The reasoning behind the decision\n "command": // The command to be executed\n}\n\nThe properties ( task_done, thoughts, command ) are mandatory on each response.\nGive the command one at a time to solve the given task. As long as you\'re not done with the task, set task_done to false.\nWhen you are sure that the task is completed, set task_done to true, set command to empty string and provide your final thoughts in the thoughts field.\nDon\'t add any chat or extra messages outside the json format. Because the system will parse only the json response.\nAny of your thoughts must be in the \'thoughts\' field.\n\nafter each command, the system will execute the command and respond to you with the output.\nEnsure to run only one command at a time.\nNEVER use commands that produce large amounts of output or take a long time to run to avoid exceeding context limits.\nUse specific patterns: \'find -name "*.c" -maxdepth 2\' instead of recursive exploration.\nNo human is involved in the task. So, don\'t seek human intervention.\n\nRemember following important points\n1. If a command fails, analyze the error message and provide an alternative command in your next response. Same command will not pass again.\n2. Avoid using recursive commands like \'ls -R\', \'rm -rf\', \'tree\', or \'find\' without depth limits as they can produce excessive output or be destructive.\n3. You cannot run any interactive commands like vim, nano, etc.\n\n You are a helpful log analysis bot. Your job is to analyze a log file and identify the root-cause if there are any failure. You\'ll be given read-only access to the code from where the log is generated. The read-only code is available at //workdir/code.\n\nThe log file to analyze will be given in the user prompt. You can find the provided log file under the directory //var/log/\n\nOnly when you have run all necessary commands and identified the root cause, you should give me the final result.\n '}, {'role': 'user', 'content': '\n Analyze the log file `/var/log`\n '}, {'role': 'assistant', 'content': '{"task_done": false, "thoughts": "First, I need to see what files exist under /var/log to identify the target log file(s) for analysis.", "command": "ls -1 /var/log"}'}, {'role': 'user', 'content': 'ShellCommunicator.log\nalternatives.log\napt\nbtmp\nbuild.log\ndpkg.log\nfontconfig.log\nlastlog\nwtmp'}, {'role': 'assistant', 'content': '{"task_done": false, "thoughts": "Identify which log contains failures. Start with build.log as it\'s commonly used for build errors, but first check its length to avoid dumping huge content.", "command": "wc -l /var/log/build.log 2>/dev/null || echo \'no build.log or not regular file\'"}'}, {'role': 'user', 'content': '7 /var/log/build.log'}], 'model': 'gpt-5-swe-agent'}} +DEBUG:openai._base_client:Sending HTTP Request: POST https://azlinux-chatbot-2025.openai.azure.com/openai/v1/responses +DEBUG:httpcore.http11:send_request_headers.started request= +DEBUG:httpcore.http11:send_request_headers.complete +DEBUG:httpcore.http11:send_request_body.started request= +DEBUG:httpcore.http11:send_request_body.complete +DEBUG:httpcore.http11:receive_response_headers.started request= +DEBUG:httpcore.http11:receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Content-Length', b'3393'), (b'Content-Type', b'application/json'), (b'skip-error-remapping', b'true'), (b'x-ms-is-spilled-over', b'false'), (b'x-ratelimit-key', b'gpt-5-swe-agent'), (b'x-ratelimit-remaining-requests', b'1499'), (b'x-ratelimit-reset-requests', b'0'), (b'x-ratelimit-limit-requests', b'1500'), (b'x-ratelimit-renewalperiod-requests', b'60'), (b'x-ratelimit-abusepenalty-active', b'False'), (b'x-ratelimit-remaining-tokens', b'149245'), (b'x-ratelimit-reset-tokens', b'0'), (b'x-ratelimit-limit-tokens', b'150000'), (b'x-ratelimit-renewalperiod-tokens', b'60'), (b'azureai-fe-is-streaming', b'False'), (b'x-ms-served-model', b'gpt-5-2025-08-07'), (b'x-request-id', b'b0910cc0-7b9f-4943-a9b2-907637854296'), (b'apim-request-id', b'b370b06a-5f05-4196-8c43-bca3ca0dd116'), (b'Strict-Transport-Security', b'max-age=31536000; includeSubDomains; preload'), (b'x-ms-client-request-id', b'Not-Set'), (b'x-content-type-options', b'nosniff'), (b'x-ms-region', b'East US 2'), (b'Date', b'Sat, 23 May 2026 03:26:34 GMT')]) +INFO:httpx:HTTP Request: POST https://azlinux-chatbot-2025.openai.azure.com/openai/v1/responses "HTTP/1.1 200 OK" +DEBUG:httpcore.http11:receive_response_body.started request= +DEBUG:httpcore.http11:receive_response_body.complete +DEBUG:httpcore.http11:response_closed.started +DEBUG:httpcore.http11:response_closed.complete +DEBUG:openai._base_client:HTTP Response: POST https://azlinux-chatbot-2025.openai.azure.com/openai/v1/responses "200 OK" Headers({'content-length': '3393', 'content-type': 'application/json', 'skip-error-remapping': 'true', 'x-ms-is-spilled-over': 'false', 'x-ratelimit-key': 'gpt-5-swe-agent', 'x-ratelimit-remaining-requests': '1499', 'x-ratelimit-reset-requests': '0', 'x-ratelimit-limit-requests': '1500', 'x-ratelimit-renewalperiod-requests': '60', 'x-ratelimit-abusepenalty-active': 'False', 'x-ratelimit-remaining-tokens': '149245', 'x-ratelimit-reset-tokens': '0', 'x-ratelimit-limit-tokens': '150000', 'x-ratelimit-renewalperiod-tokens': '60', 'azureai-fe-is-streaming': 'False', 'x-ms-served-model': 'gpt-5-2025-08-07', 'x-request-id': 'b0910cc0-7b9f-4943-a9b2-907637854296', 'apim-request-id': 'b370b06a-5f05-4196-8c43-bca3ca0dd116', 'strict-transport-security': 'max-age=31536000; includeSubDomains; preload', 'x-ms-client-request-id': 'Not-Set', 'x-content-type-options': 'nosniff', 'x-ms-region': 'East US 2', 'date': 'Sat, 23 May 2026 03:26:34 GMT'}) +DEBUG:openai._base_client:request_id: b0910cc0-7b9f-4943-a9b2-907637854296 +INFO:microbots.llm.llm:The llm response is {'task_done': False, 'thoughts': 'The build.log is small; display its contents to analyze any errors or warnings.', 'command': "sed -n '1,120p' /var/log/build.log"} +INFO: MicroBot :-------------------- Step-3 -------------------- +INFO: MicroBot : πŸ’­ LLM thoughts: The build.log is small; display its contents to analyze any errors or warnings. +INFO: MicroBot : ➑️ LLM tool call : "sed -n '1,120p' /var/log/build.log" +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:➑️ Executing command in container: sed -n '1,120p' /var/log/build.log +DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): localhost:58241 +DEBUG:urllib3.connectionpool:http://localhost:58241 "POST / HTTP/1.1" 200 260 +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:Command completed in 0.00s +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:⬅️ Return Code: 0, +Stdout: +app.c: In function β€˜add’: +app.c:5:17: error: expected β€˜;’ before β€˜}’ token + 5 | return a + b + | ^ + | ; + 6 | } + | ~ +Stderr: + +DEBUG: MicroBot : πŸ”§ Command executed. +Return Code: 0 +Stdout: +app.c: In function β€˜add’: +app.c:5:17: error: expected β€˜;’ before β€˜}’ token + 5 | return a + b + | ^ + | ; + 6 | } + | ~ +Stderr: + +INFO: MicroBot : ⬅️ Command output: +app.c: In function β€˜add’: +app.c:5:17: error: expected β€˜;’ before β€˜}’ token + 5 | return a + b + | ^ + | ; + 6 | } + | ~ +DEBUG:openai._base_client:Request options: {'method': 'post', 'url': '/responses', 'files': None, 'idempotency_key': 'stainless-python-retry-bc98c4aa-e5db-496a-8522-e3ee477f38a9', 'json_data': {'input': [{'role': 'system', 'content': '\n \nYou are a helpful agent well versed in software development and debugging.\n\nYou will be provided with a coding or debugging task to complete inside a sandboxed shell environment.\nThere is a shell session open for you.\nYou will be provided with a task and you should achieve it using the shell commands.\nAll your response must be in the following json format:\n\n{\n "task_done": , // Indicates if the task is completed\n "thoughts": , // The reasoning behind the decision\n "command": // The command to be executed\n}\n\nThe properties ( task_done, thoughts, command ) are mandatory on each response.\nGive the command one at a time to solve the given task. As long as you\'re not done with the task, set task_done to false.\nWhen you are sure that the task is completed, set task_done to true, set command to empty string and provide your final thoughts in the thoughts field.\nDon\'t add any chat or extra messages outside the json format. Because the system will parse only the json response.\nAny of your thoughts must be in the \'thoughts\' field.\n\nafter each command, the system will execute the command and respond to you with the output.\nEnsure to run only one command at a time.\nNEVER use commands that produce large amounts of output or take a long time to run to avoid exceeding context limits.\nUse specific patterns: \'find -name "*.c" -maxdepth 2\' instead of recursive exploration.\nNo human is involved in the task. So, don\'t seek human intervention.\n\nRemember following important points\n1. If a command fails, analyze the error message and provide an alternative command in your next response. Same command will not pass again.\n2. Avoid using recursive commands like \'ls -R\', \'rm -rf\', \'tree\', or \'find\' without depth limits as they can produce excessive output or be destructive.\n3. You cannot run any interactive commands like vim, nano, etc.\n\n You are a helpful log analysis bot. Your job is to analyze a log file and identify the root-cause if there are any failure. You\'ll be given read-only access to the code from where the log is generated. The read-only code is available at //workdir/code.\n\nThe log file to analyze will be given in the user prompt. You can find the provided log file under the directory //var/log/\n\nOnly when you have run all necessary commands and identified the root cause, you should give me the final result.\n '}, {'role': 'user', 'content': '\n Analyze the log file `/var/log`\n '}, {'role': 'assistant', 'content': '{"task_done": false, "thoughts": "First, I need to see what files exist under /var/log to identify the target log file(s) for analysis.", "command": "ls -1 /var/log"}'}, {'role': 'user', 'content': 'ShellCommunicator.log\nalternatives.log\napt\nbtmp\nbuild.log\ndpkg.log\nfontconfig.log\nlastlog\nwtmp'}, {'role': 'assistant', 'content': '{"task_done": false, "thoughts": "Identify which log contains failures. Start with build.log as it\'s commonly used for build errors, but first check its length to avoid dumping huge content.", "command": "wc -l /var/log/build.log 2>/dev/null || echo \'no build.log or not regular file\'"}'}, {'role': 'user', 'content': '7 /var/log/build.log'}, {'role': 'assistant', 'content': '{"task_done": false, "thoughts": "The build.log is small; display its contents to analyze any errors or warnings.", "command": "sed -n \'1,120p\' /var/log/build.log"}'}, {'role': 'user', 'content': 'app.c: In function β€˜add’:\napp.c:5:17: error: expected β€˜;’ before β€˜}’ token\n 5 | return a + b\n | ^\n | ;\n 6 | }\n | ~'}], 'model': 'gpt-5-swe-agent'}} +DEBUG:openai._base_client:Sending HTTP Request: POST https://azlinux-chatbot-2025.openai.azure.com/openai/v1/responses +DEBUG:httpcore.http11:send_request_headers.started request= +DEBUG:httpcore.http11:send_request_headers.complete +DEBUG:httpcore.http11:send_request_body.started request= +DEBUG:httpcore.http11:send_request_body.complete +DEBUG:httpcore.http11:receive_response_headers.started request= +DEBUG:httpcore.http11:receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Content-Length', b'3417'), (b'Content-Type', b'application/json'), (b'skip-error-remapping', b'true'), (b'x-ms-is-spilled-over', b'false'), (b'x-ratelimit-key', b'gpt-5-swe-agent'), (b'x-ratelimit-remaining-requests', b'1499'), (b'x-ratelimit-reset-requests', b'0'), (b'x-ratelimit-limit-requests', b'1500'), (b'x-ratelimit-renewalperiod-requests', b'60'), (b'x-ratelimit-abusepenalty-active', b'False'), (b'x-ratelimit-remaining-tokens', b'149161'), (b'x-ratelimit-reset-tokens', b'0'), (b'x-ratelimit-limit-tokens', b'150000'), (b'x-ratelimit-renewalperiod-tokens', b'60'), (b'azureai-fe-is-streaming', b'False'), (b'x-ms-served-model', b'gpt-5-2025-08-07'), (b'x-request-id', b'3c3aec9f-bbd9-47b2-943d-4a5c8f52fefe'), (b'apim-request-id', b'fb7528d8-6f51-40e2-93f4-f176fa9ec7c6'), (b'Strict-Transport-Security', b'max-age=31536000; includeSubDomains; preload'), (b'x-ms-client-request-id', b'Not-Set'), (b'x-content-type-options', b'nosniff'), (b'x-ms-region', b'East US 2'), (b'Date', b'Sat, 23 May 2026 03:26:37 GMT')]) +INFO:httpx:HTTP Request: POST https://azlinux-chatbot-2025.openai.azure.com/openai/v1/responses "HTTP/1.1 200 OK" +DEBUG:httpcore.http11:receive_response_body.started request= +DEBUG:httpcore.http11:receive_response_body.complete +DEBUG:httpcore.http11:response_closed.started +DEBUG:httpcore.http11:response_closed.complete +DEBUG:openai._base_client:HTTP Response: POST https://azlinux-chatbot-2025.openai.azure.com/openai/v1/responses "200 OK" Headers({'content-length': '3417', 'content-type': 'application/json', 'skip-error-remapping': 'true', 'x-ms-is-spilled-over': 'false', 'x-ratelimit-key': 'gpt-5-swe-agent', 'x-ratelimit-remaining-requests': '1499', 'x-ratelimit-reset-requests': '0', 'x-ratelimit-limit-requests': '1500', 'x-ratelimit-renewalperiod-requests': '60', 'x-ratelimit-abusepenalty-active': 'False', 'x-ratelimit-remaining-tokens': '149161', 'x-ratelimit-reset-tokens': '0', 'x-ratelimit-limit-tokens': '150000', 'x-ratelimit-renewalperiod-tokens': '60', 'azureai-fe-is-streaming': 'False', 'x-ms-served-model': 'gpt-5-2025-08-07', 'x-request-id': '3c3aec9f-bbd9-47b2-943d-4a5c8f52fefe', 'apim-request-id': 'fb7528d8-6f51-40e2-93f4-f176fa9ec7c6', 'strict-transport-security': 'max-age=31536000; includeSubDomains; preload', 'x-ms-client-request-id': 'Not-Set', 'x-content-type-options': 'nosniff', 'x-ms-region': 'East US 2', 'date': 'Sat, 23 May 2026 03:26:37 GMT'}) +DEBUG:openai._base_client:request_id: 3c3aec9f-bbd9-47b2-943d-4a5c8f52fefe +INFO:microbots.llm.llm:The llm response is {'task_done': False, 'thoughts': 'Open the code directory to inspect app.c referenced in the build.log and confirm the syntax error.', 'command': 'ls -1 //workdir/code'} +INFO: MicroBot :-------------------- Step-4 -------------------- +INFO: MicroBot : πŸ’­ LLM thoughts: Open the code directory to inspect app.c referenced in the build.log and confirm the syntax error. +INFO: MicroBot : ➑️ LLM tool call : "ls -1 //workdir/code" +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:➑️ Executing command in container: ls -1 //workdir/code +DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): localhost:58241 +DEBUG:urllib3.connectionpool:http://localhost:58241 "POST / HTTP/1.1" 200 87 +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:Command completed in 0.00s +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:⬅️ Return Code: 0, +Stdout: +app.c +build.log +Stderr: + +DEBUG: MicroBot : πŸ”§ Command executed. +Return Code: 0 +Stdout: +app.c +build.log +Stderr: + +INFO: MicroBot : ⬅️ Command output: +app.c +build.log +DEBUG:openai._base_client:Request options: {'method': 'post', 'url': '/responses', 'files': None, 'idempotency_key': 'stainless-python-retry-72314b96-e05c-409d-a1be-956a9e2b1559', 'json_data': {'input': [{'role': 'system', 'content': '\n \nYou are a helpful agent well versed in software development and debugging.\n\nYou will be provided with a coding or debugging task to complete inside a sandboxed shell environment.\nThere is a shell session open for you.\nYou will be provided with a task and you should achieve it using the shell commands.\nAll your response must be in the following json format:\n\n{\n "task_done": , // Indicates if the task is completed\n "thoughts": , // The reasoning behind the decision\n "command": // The command to be executed\n}\n\nThe properties ( task_done, thoughts, command ) are mandatory on each response.\nGive the command one at a time to solve the given task. As long as you\'re not done with the task, set task_done to false.\nWhen you are sure that the task is completed, set task_done to true, set command to empty string and provide your final thoughts in the thoughts field.\nDon\'t add any chat or extra messages outside the json format. Because the system will parse only the json response.\nAny of your thoughts must be in the \'thoughts\' field.\n\nafter each command, the system will execute the command and respond to you with the output.\nEnsure to run only one command at a time.\nNEVER use commands that produce large amounts of output or take a long time to run to avoid exceeding context limits.\nUse specific patterns: \'find -name "*.c" -maxdepth 2\' instead of recursive exploration.\nNo human is involved in the task. So, don\'t seek human intervention.\n\nRemember following important points\n1. If a command fails, analyze the error message and provide an alternative command in your next response. Same command will not pass again.\n2. Avoid using recursive commands like \'ls -R\', \'rm -rf\', \'tree\', or \'find\' without depth limits as they can produce excessive output or be destructive.\n3. You cannot run any interactive commands like vim, nano, etc.\n\n You are a helpful log analysis bot. Your job is to analyze a log file and identify the root-cause if there are any failure. You\'ll be given read-only access to the code from where the log is generated. The read-only code is available at //workdir/code.\n\nThe log file to analyze will be given in the user prompt. You can find the provided log file under the directory //var/log/\n\nOnly when you have run all necessary commands and identified the root cause, you should give me the final result.\n '}, {'role': 'user', 'content': '\n Analyze the log file `/var/log`\n '}, {'role': 'assistant', 'content': '{"task_done": false, "thoughts": "First, I need to see what files exist under /var/log to identify the target log file(s) for analysis.", "command": "ls -1 /var/log"}'}, {'role': 'user', 'content': 'ShellCommunicator.log\nalternatives.log\napt\nbtmp\nbuild.log\ndpkg.log\nfontconfig.log\nlastlog\nwtmp'}, {'role': 'assistant', 'content': '{"task_done": false, "thoughts": "Identify which log contains failures. Start with build.log as it\'s commonly used for build errors, but first check its length to avoid dumping huge content.", "command": "wc -l /var/log/build.log 2>/dev/null || echo \'no build.log or not regular file\'"}'}, {'role': 'user', 'content': '7 /var/log/build.log'}, {'role': 'assistant', 'content': '{"task_done": false, "thoughts": "The build.log is small; display its contents to analyze any errors or warnings.", "command": "sed -n \'1,120p\' /var/log/build.log"}'}, {'role': 'user', 'content': 'app.c: In function β€˜add’:\napp.c:5:17: error: expected β€˜;’ before β€˜}’ token\n 5 | return a + b\n | ^\n | ;\n 6 | }\n | ~'}, {'role': 'assistant', 'content': '{"task_done": false, "thoughts": "Open the code directory to inspect app.c referenced in the build.log and confirm the syntax error.", "command": "ls -1 //workdir/code"}'}, {'role': 'user', 'content': 'app.c\nbuild.log'}], 'model': 'gpt-5-swe-agent'}} +DEBUG:openai._base_client:Sending HTTP Request: POST https://azlinux-chatbot-2025.openai.azure.com/openai/v1/responses +DEBUG:httpcore.http11:send_request_headers.started request= +DEBUG:httpcore.http11:send_request_headers.complete +DEBUG:httpcore.http11:send_request_body.started request= +DEBUG:httpcore.http11:send_request_body.complete +DEBUG:httpcore.http11:receive_response_headers.started request= +DEBUG:httpcore.http11:receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Content-Length', b'3385'), (b'Content-Type', b'application/json'), (b'skip-error-remapping', b'true'), (b'x-ms-is-spilled-over', b'false'), (b'x-ratelimit-key', b'gpt-5-swe-agent'), (b'x-ratelimit-remaining-requests', b'1499'), (b'x-ratelimit-reset-requests', b'0'), (b'x-ratelimit-limit-requests', b'1500'), (b'x-ratelimit-renewalperiod-requests', b'60'), (b'x-ratelimit-abusepenalty-active', b'False'), (b'x-ratelimit-remaining-tokens', b'149115'), (b'x-ratelimit-reset-tokens', b'0'), (b'x-ratelimit-limit-tokens', b'150000'), (b'x-ratelimit-renewalperiod-tokens', b'60'), (b'azureai-fe-is-streaming', b'False'), (b'x-ms-served-model', b'gpt-5-2025-08-07'), (b'x-request-id', b'97d588c8-c33c-4a39-b9fa-3e274b3d1ddd'), (b'apim-request-id', b'a3ac38e9-5f82-496e-8ed1-466de0e10980'), (b'Strict-Transport-Security', b'max-age=31536000; includeSubDomains; preload'), (b'x-ms-client-request-id', b'Not-Set'), (b'x-content-type-options', b'nosniff'), (b'x-ms-region', b'East US 2'), (b'Date', b'Sat, 23 May 2026 03:26:40 GMT')]) +INFO:httpx:HTTP Request: POST https://azlinux-chatbot-2025.openai.azure.com/openai/v1/responses "HTTP/1.1 200 OK" +DEBUG:httpcore.http11:receive_response_body.started request= +DEBUG:httpcore.http11:receive_response_body.complete +DEBUG:httpcore.http11:response_closed.started +DEBUG:httpcore.http11:response_closed.complete +DEBUG:openai._base_client:HTTP Response: POST https://azlinux-chatbot-2025.openai.azure.com/openai/v1/responses "200 OK" Headers({'content-length': '3385', 'content-type': 'application/json', 'skip-error-remapping': 'true', 'x-ms-is-spilled-over': 'false', 'x-ratelimit-key': 'gpt-5-swe-agent', 'x-ratelimit-remaining-requests': '1499', 'x-ratelimit-reset-requests': '0', 'x-ratelimit-limit-requests': '1500', 'x-ratelimit-renewalperiod-requests': '60', 'x-ratelimit-abusepenalty-active': 'False', 'x-ratelimit-remaining-tokens': '149115', 'x-ratelimit-reset-tokens': '0', 'x-ratelimit-limit-tokens': '150000', 'x-ratelimit-renewalperiod-tokens': '60', 'azureai-fe-is-streaming': 'False', 'x-ms-served-model': 'gpt-5-2025-08-07', 'x-request-id': '97d588c8-c33c-4a39-b9fa-3e274b3d1ddd', 'apim-request-id': 'a3ac38e9-5f82-496e-8ed1-466de0e10980', 'strict-transport-security': 'max-age=31536000; includeSubDomains; preload', 'x-ms-client-request-id': 'Not-Set', 'x-content-type-options': 'nosniff', 'x-ms-region': 'East US 2', 'date': 'Sat, 23 May 2026 03:26:40 GMT'}) +DEBUG:openai._base_client:request_id: 97d588c8-c33c-4a39-b9fa-3e274b3d1ddd +INFO:microbots.llm.llm:The llm response is {'task_done': False, 'thoughts': 'View the source file to confirm the syntax error location and cause.', 'command': "sed -n '1,120p' //workdir/code/app.c"} +INFO: MicroBot :-------------------- Step-5 -------------------- +INFO: MicroBot : πŸ’­ LLM thoughts: View the source file to confirm the syntax error location and cause. +INFO: MicroBot : ➑️ LLM tool call : "sed -n '1,120p' //workdir/code/app.c" +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:➑️ Executing command in container: sed -n '1,120p' //workdir/code/app.c +DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): localhost:58241 +DEBUG:urllib3.connectionpool:http://localhost:58241 "POST / HTTP/1.1" 200 319 +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:Command completed in 0.00s +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:⬅️ Return Code: 0, +Stdout: +// app.c β€” A simple greeting program with a syntax error +#include + +int add(int a, int b) { + return a + b +} + +int main(void) { + printf("Hello, Microbots!\n"); + printf("2 + 3 = %d\n", add(2, 3)); + return 0; +} + +Stderr: + +DEBUG: MicroBot : πŸ”§ Command executed. +Return Code: 0 +Stdout: +// app.c β€” A simple greeting program with a syntax error +#include + +int add(int a, int b) { + return a + b +} + +int main(void) { + printf("Hello, Microbots!\n"); + printf("2 + 3 = %d\n", add(2, 3)); + return 0; +} + +Stderr: + +INFO: MicroBot : ⬅️ Command output: +// app.c β€” A simple greeting program with a syntax error +#include + +int add(int a, int b) { + return a + b +} + +int main(void) { + printf("Hello, Microbots!\n"); + printf("2 + 3 = %d\n", add(2, 3)); + return 0; +} + +DEBUG:openai._base_client:Request options: {'method': 'post', 'url': '/responses', 'files': None, 'idempotency_key': 'stainless-python-retry-ab5d3110-8393-4095-ad6c-7b3b1fd0ea94', 'json_data': {'input': [{'role': 'system', 'content': '\n \nYou are a helpful agent well versed in software development and debugging.\n\nYou will be provided with a coding or debugging task to complete inside a sandboxed shell environment.\nThere is a shell session open for you.\nYou will be provided with a task and you should achieve it using the shell commands.\nAll your response must be in the following json format:\n\n{\n "task_done": , // Indicates if the task is completed\n "thoughts": , // The reasoning behind the decision\n "command": // The command to be executed\n}\n\nThe properties ( task_done, thoughts, command ) are mandatory on each response.\nGive the command one at a time to solve the given task. As long as you\'re not done with the task, set task_done to false.\nWhen you are sure that the task is completed, set task_done to true, set command to empty string and provide your final thoughts in the thoughts field.\nDon\'t add any chat or extra messages outside the json format. Because the system will parse only the json response.\nAny of your thoughts must be in the \'thoughts\' field.\n\nafter each command, the system will execute the command and respond to you with the output.\nEnsure to run only one command at a time.\nNEVER use commands that produce large amounts of output or take a long time to run to avoid exceeding context limits.\nUse specific patterns: \'find -name "*.c" -maxdepth 2\' instead of recursive exploration.\nNo human is involved in the task. So, don\'t seek human intervention.\n\nRemember following important points\n1. If a command fails, analyze the error message and provide an alternative command in your next response. Same command will not pass again.\n2. Avoid using recursive commands like \'ls -R\', \'rm -rf\', \'tree\', or \'find\' without depth limits as they can produce excessive output or be destructive.\n3. You cannot run any interactive commands like vim, nano, etc.\n\n You are a helpful log analysis bot. Your job is to analyze a log file and identify the root-cause if there are any failure. You\'ll be given read-only access to the code from where the log is generated. The read-only code is available at //workdir/code.\n\nThe log file to analyze will be given in the user prompt. You can find the provided log file under the directory //var/log/\n\nOnly when you have run all necessary commands and identified the root cause, you should give me the final result.\n '}, {'role': 'user', 'content': '\n Analyze the log file `/var/log`\n '}, {'role': 'assistant', 'content': '{"task_done": false, "thoughts": "First, I need to see what files exist under /var/log to identify the target log file(s) for analysis.", "command": "ls -1 /var/log"}'}, {'role': 'user', 'content': 'ShellCommunicator.log\nalternatives.log\napt\nbtmp\nbuild.log\ndpkg.log\nfontconfig.log\nlastlog\nwtmp'}, {'role': 'assistant', 'content': '{"task_done": false, "thoughts": "Identify which log contains failures. Start with build.log as it\'s commonly used for build errors, but first check its length to avoid dumping huge content.", "command": "wc -l /var/log/build.log 2>/dev/null || echo \'no build.log or not regular file\'"}'}, {'role': 'user', 'content': '7 /var/log/build.log'}, {'role': 'assistant', 'content': '{"task_done": false, "thoughts": "The build.log is small; display its contents to analyze any errors or warnings.", "command": "sed -n \'1,120p\' /var/log/build.log"}'}, {'role': 'user', 'content': 'app.c: In function β€˜add’:\napp.c:5:17: error: expected β€˜;’ before β€˜}’ token\n 5 | return a + b\n | ^\n | ;\n 6 | }\n | ~'}, {'role': 'assistant', 'content': '{"task_done": false, "thoughts": "Open the code directory to inspect app.c referenced in the build.log and confirm the syntax error.", "command": "ls -1 //workdir/code"}'}, {'role': 'user', 'content': 'app.c\nbuild.log'}, {'role': 'assistant', 'content': '{"task_done": false, "thoughts": "View the source file to confirm the syntax error location and cause.", "command": "sed -n \'1,120p\' //workdir/code/app.c"}'}, {'role': 'user', 'content': '// app.c β€” A simple greeting program with a syntax error\n#include \n\nint add(int a, int b) {\n return a + b\n}\n\nint main(void) {\n printf("Hello, Microbots!\\n");\n printf("2 + 3 = %d\\n", add(2, 3));\n return 0;\n}\n'}], 'model': 'gpt-5-swe-agent'}} +DEBUG:openai._base_client:Sending HTTP Request: POST https://azlinux-chatbot-2025.openai.azure.com/openai/v1/responses +DEBUG:httpcore.http11:send_request_headers.started request= +DEBUG:httpcore.http11:send_request_headers.complete +DEBUG:httpcore.http11:send_request_body.started request= +DEBUG:httpcore.http11:send_request_body.complete +DEBUG:httpcore.http11:receive_response_headers.started request= +DEBUG:httpcore.http11:receive_response_headers.complete return_value=(b'HTTP/1.1', 200, b'OK', [(b'Content-Length', b'3671'), (b'Content-Type', b'application/json'), (b'skip-error-remapping', b'true'), (b'x-ms-is-spilled-over', b'false'), (b'x-ratelimit-key', b'gpt-5-swe-agent'), (b'x-ratelimit-remaining-requests', b'1499'), (b'x-ratelimit-reset-requests', b'0'), (b'x-ratelimit-limit-requests', b'1500'), (b'x-ratelimit-renewalperiod-requests', b'60'), (b'x-ratelimit-abusepenalty-active', b'False'), (b'x-ratelimit-remaining-tokens', b'149019'), (b'x-ratelimit-reset-tokens', b'0'), (b'x-ratelimit-limit-tokens', b'150000'), (b'x-ratelimit-renewalperiod-tokens', b'60'), (b'azureai-fe-is-streaming', b'False'), (b'x-ms-served-model', b'gpt-5-2025-08-07'), (b'x-request-id', b'44639273-62ce-4745-9a38-312df81a6a55'), (b'apim-request-id', b'ded44f61-5684-4b49-923d-c7753490e401'), (b'Strict-Transport-Security', b'max-age=31536000; includeSubDomains; preload'), (b'x-ms-client-request-id', b'Not-Set'), (b'x-content-type-options', b'nosniff'), (b'x-ms-region', b'East US 2'), (b'Date', b'Sat, 23 May 2026 03:26:47 GMT')]) +INFO:httpx:HTTP Request: POST https://azlinux-chatbot-2025.openai.azure.com/openai/v1/responses "HTTP/1.1 200 OK" +DEBUG:httpcore.http11:receive_response_body.started request= +DEBUG:httpcore.http11:receive_response_body.complete +DEBUG:httpcore.http11:response_closed.started +DEBUG:httpcore.http11:response_closed.complete +DEBUG:openai._base_client:HTTP Response: POST https://azlinux-chatbot-2025.openai.azure.com/openai/v1/responses "200 OK" Headers({'content-length': '3671', 'content-type': 'application/json', 'skip-error-remapping': 'true', 'x-ms-is-spilled-over': 'false', 'x-ratelimit-key': 'gpt-5-swe-agent', 'x-ratelimit-remaining-requests': '1499', 'x-ratelimit-reset-requests': '0', 'x-ratelimit-limit-requests': '1500', 'x-ratelimit-renewalperiod-requests': '60', 'x-ratelimit-abusepenalty-active': 'False', 'x-ratelimit-remaining-tokens': '149019', 'x-ratelimit-reset-tokens': '0', 'x-ratelimit-limit-tokens': '150000', 'x-ratelimit-renewalperiod-tokens': '60', 'azureai-fe-is-streaming': 'False', 'x-ms-served-model': 'gpt-5-2025-08-07', 'x-request-id': '44639273-62ce-4745-9a38-312df81a6a55', 'apim-request-id': 'ded44f61-5684-4b49-923d-c7753490e401', 'strict-transport-security': 'max-age=31536000; includeSubDomains; preload', 'x-ms-client-request-id': 'Not-Set', 'x-content-type-options': 'nosniff', 'x-ms-region': 'East US 2', 'date': 'Sat, 23 May 2026 03:26:47 GMT'}) +DEBUG:openai._base_client:request_id: 44639273-62ce-4745-9a38-312df81a6a55 +INFO:microbots.llm.llm:The llm response is {'task_done': True, 'thoughts': "Root cause identified from /var/log/build.log: C compilation fails due to a syntax error in //workdir/code/app.c. Specifically, in function add (line 5), the return statement is missing a trailing semicolon: 'return a + b' should be 'return a + b;'. This triggers the compiler error: 'expected ';' before '}' token'. Fix: add the semicolon after the return expression.", 'command': ''} +INFO: MicroBot : πŸ’­ LLM final thoughts: Root cause identified from /var/log/build.log: C compilation fails due to a syntax error in //workdir/code/app.c. Specifically, in function add (line 5), the return statement is missing a trailing semicolon: 'return a + b' should be 'return a + b;'. This triggers the compiler error: 'expected ';' before '}' token'. Fix: add the semicolon after the return expression. +INFO: MicroBot :πŸ”š TASK COMPLETED : + An... +Root cause identified from /var/log/build.log: C compilation fails due to a syntax error in //workdir/code/app.c. Specifically, in function add (line 5), the return statement is missing a trailing semicolon: 'return a + b' should be 'return a + b;'. This triggers the compiler error: 'expected ';' before '}' token'. Fix: add the semicolon after the return expression. +INFO:microbots.environment.local_docker.LocalDockerEnvironment:πŸ› οΈ Tearing down overlay mount for code +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:➑️ Executing command in container: umount -l //workdir/code +DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): localhost:58241 +DEBUG:urllib3.connectionpool:http://localhost:58241 "POST / HTTP/1.1" 200 71 +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:Command completed in 0.01s +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:⬅️ Return Code: 0, +Stdout: + +Stderr: + +INFO:microbots.environment.local_docker.LocalDockerEnvironment:βœ… Unmounted overlay for code +INFO:microbots.environment.local_docker.LocalDockerEnvironment:πŸ›‘ Removing overlay dirs at //workdir/code and /workdir/overlay/ +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:➑️ Executing command in container: rm -rf //workdir/code && rm -rf /workdir/overlay/ +DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): localhost:58241 +DEBUG:urllib3.connectionpool:http://localhost:58241 "POST / HTTP/1.1" 200 71 +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:Command completed in 0.00s +DEBUG:microbots.environment.local_docker.LocalDockerEnvironment:⬅️ Return Code: 0, +Stdout: + +Stderr: + +INFO:microbots.environment.local_docker.LocalDockerEnvironment:πŸ—‘οΈ Removed overlay directories for code +DEBUG:urllib3.connectionpool:http://localhost:None "POST /v1.54/containers/5f1012fd83ae4a70bc9c7223afe67345c4bb467557ae711794e26217fd23fdbf/stop HTTP/1.1" 204 0 +DEBUG:urllib3.connectionpool:http://localhost:None "DELETE /v1.54/containers/5f1012fd83ae4a70bc9c7223afe67345c4bb467557ae711794e26217fd23fdbf?v=False&link=False&force=False HTTP/1.1" 204 0 +INFO:microbots.environment.local_docker.LocalDockerEnvironment:πŸ—‘οΈ Removed working directory at /home/sikannan/MICROBOTS_WORKDIR_79b91420 +DEBUG:httpcore.connection:close.started +DEBUG:httpcore.connection:close.complete \ No newline at end of file diff --git a/docs/examples/microbots_introduction/log_analysis_logger_info.txt b/docs/examples/microbots_introduction/log_analysis_logger_info.txt new file mode 100644 index 0000000..e97f5e8 --- /dev/null +++ b/docs/examples/microbots_introduction/log_analysis_logger_info.txt @@ -0,0 +1,90 @@ +(.venv) sikannan@sikannan-ubuntu-vm:~/codeBase/microbots-introduction$ python3 log_analysis_bot.py +INFO:microbots.environment.local_docker.LocalDockerEnvironment:πŸ—‚οΈ Created working directory at /home/sikannan/MICROBOTS_WORKDIR_da35245a +INFO:microbots.environment.local_docker.LocalDockerEnvironment:πŸ“¦ Volume mapping: /home/sikannan/codeBase/microbots-introduction/code β†’ /ro/code +INFO:microbots.environment.local_docker.LocalDockerEnvironment:πŸš€ Started container 3ebc67c5e0c6 with image kavyasree261002/shell_server:latest on host port 44517 +INFO:microbots.environment.local_docker.LocalDockerEnvironment:πŸ”’ Set up overlay mount for read-only directory at /workdir/code +INFO:microbots.environment.local_docker.LocalDockerEnvironment:βœ… Successfully copied /home/sikannan/codeBase/microbots-introduction/code/build.log to container:/var/log +INFO:httpx:HTTP Request: POST https://azlinux-chatbot-2025.openai.azure.com/openai/v1/responses "HTTP/1.1 200 OK" +INFO:microbots.llm.llm:The llm response is {'task_done': False, 'thoughts': 'Start by listing the contents of /var/log to identify the relevant log file to analyze.', 'command': 'ls -1 /var/log'} +INFO: MicroBot : ℹ️ TASK STARTED : + Analyze the log file `/var/log` + ... +INFO: MicroBot :-------------------- Step-1 -------------------- +INFO: MicroBot : πŸ’­ LLM thoughts: Start by listing the contents of /var/log to identify the relevant log file to analyze. +INFO: MicroBot : ➑️ LLM tool call : "ls -1 /var/log" +INFO: MicroBot : ⬅️ Command output: +ShellCommunicator.log +alternatives.log +apt +btmp +build.log +dpkg.log +fontconfig.log +lastlog +wtmp +INFO:httpx:HTTP Request: POST https://azlinux-chatbot-2025.openai.azure.com/openai/v1/responses "HTTP/1.1 200 OK" +INFO:microbots.llm.llm:The llm response is {'task_done': False, 'thoughts': 'Determine sizes to choose which logs to open safely without producing excessive output.', 'command': 'ls -lh /var/log'} +INFO: MicroBot :-------------------- Step-2 -------------------- +INFO: MicroBot : πŸ’­ LLM thoughts: Determine sizes to choose which logs to open safely without producing excessive output. +INFO: MicroBot : ➑️ LLM tool call : "ls -lh /var/log" +INFO: MicroBot : ⬅️ Command output: +total 276K +-rw-r--r-- 1 root root 3.8K May 23 03:24 ShellCommunicator.log +-rw-r--r-- 1 root root 27K Mar 11 12:28 alternatives.log +drwxr-xr-x 1 root root 4.0K Mar 11 12:31 apt +-rw-rw---- 1 root utmp 0 Feb 23 00:00 btmp +-rw-rw-r-- 1 vscode vscode 200 May 18 06:43 build.log +-rw-r--r-- 1 root root 232K Mar 11 12:31 dpkg.log +-rw-r--r-- 1 root root 605 Feb 24 20:39 fontconfig.log +-rw-rw-r-- 1 root utmp 0 Feb 23 00:00 lastlog +-rw-rw-r-- 1 root utmp 0 Feb 23 00:00 wtmp +INFO:httpx:HTTP Request: POST https://azlinux-chatbot-2025.openai.azure.com/openai/v1/responses "HTTP/1.1 200 OK" +INFO:microbots.llm.llm:The llm response is {'task_done': False, 'thoughts': 'Open the small custom build log first to check for any failures.', 'command': "sed -n '1,120p' /var/log/build.log"} +INFO: MicroBot :-------------------- Step-3 -------------------- +INFO: MicroBot : πŸ’­ LLM thoughts: Open the small custom build log first to check for any failures. +INFO: MicroBot : ➑️ LLM tool call : "sed -n '1,120p' /var/log/build.log" +INFO: MicroBot : ⬅️ Command output: +app.c: In function β€˜add’: +app.c:5:17: error: expected β€˜;’ before β€˜}’ token + 5 | return a + b + | ^ + | ; + 6 | } + | ~ +INFO:httpx:HTTP Request: POST https://azlinux-chatbot-2025.openai.azure.com/openai/v1/responses "HTTP/1.1 200 OK" +INFO:microbots.llm.llm:The llm response is {'task_done': False, 'thoughts': 'Confirm the source file that caused the build error by locating app.c in the code directory.', 'command': 'find //workdir/code -maxdepth 2 -type f -name "app.c"'} +INFO: MicroBot :-------------------- Step-4 -------------------- +INFO: MicroBot : πŸ’­ LLM thoughts: Confirm the source file that caused the build error by locating app.c in the code directory. +INFO: MicroBot : ➑️ LLM tool call : "find //workdir/code -maxdepth 2 -type f -name \"app.c\"" +INFO: MicroBot : ⬅️ Command output: +//workdir/code/app.c +INFO:httpx:HTTP Request: POST https://azlinux-chatbot-2025.openai.azure.com/openai/v1/responses "HTTP/1.1 200 OK" +INFO:microbots.llm.llm:The llm response is {'task_done': False, 'thoughts': 'View the source file to confirm the exact line and context of the syntax error mentioned in build.log.', 'command': "sed -n '1,120p' //workdir/code/app.c"} +INFO: MicroBot :-------------------- Step-5 -------------------- +INFO: MicroBot : πŸ’­ LLM thoughts: View the source file to confirm the exact line and context of the syntax error mentioned in build.log. +INFO: MicroBot : ➑️ LLM tool call : "sed -n '1,120p' //workdir/code/app.c" +INFO: MicroBot : ⬅️ Command output: +// app.c β€” A simple greeting program with a syntax error +#include + +int add(int a, int b) { + return a + b +} + +int main(void) { + printf("Hello, Microbots!\n"); + printf("2 + 3 = %d\n", add(2, 3)); + return 0; +} + +INFO:httpx:HTTP Request: POST https://azlinux-chatbot-2025.openai.azure.com/openai/v1/responses "HTTP/1.1 200 OK" +INFO:microbots.llm.llm:The llm response is {'task_done': True, 'thoughts': 'Reviewed /var/log and inspected build.log, which reports a C compilation error: "expected \';\' before \'}\' token" at app.c:5. Opened the referenced source file at //workdir/code/app.c and confirmed the root cause: the function add(int a, int b) is missing a semicolon after the return expression ("return a + b"). This syntax error causes the build failure. Fix: add a semicolon so the line reads "return a + b;" and rebuild.', 'command': ''} +INFO: MicroBot : πŸ’­ LLM final thoughts: Reviewed /var/log and inspected build.log, which reports a C compilation error: "expected ';' before '}' token" at app.c:5. Opened the referenced source file at //workdir/code/app.c and confirmed the root cause: the function add(int a, int b) is missing a semicolon after the return expression ("return a + b"). This syntax error causes the build failure. Fix: add a semicolon so the line reads "return a + b;" and rebuild. +INFO: MicroBot :πŸ”š TASK COMPLETED : + An... +Reviewed /var/log and inspected build.log, which reports a C compilation error: "expected ';' before '}' token" at app.c:5. Opened the referenced source file at //workdir/code/app.c and confirmed the root cause: the function add(int a, int b) is missing a semicolon after the return expression ("return a + b"). This syntax error causes the build failure. Fix: add a semicolon so the line reads "return a + b;" and rebuild. +INFO:microbots.environment.local_docker.LocalDockerEnvironment:πŸ› οΈ Tearing down overlay mount for code +INFO:microbots.environment.local_docker.LocalDockerEnvironment:βœ… Unmounted overlay for code +INFO:microbots.environment.local_docker.LocalDockerEnvironment:πŸ›‘ Removing overlay dirs at //workdir/code and /workdir/overlay/ +INFO:microbots.environment.local_docker.LocalDockerEnvironment:πŸ—‘οΈ Removed overlay directories for code +INFO:microbots.environment.local_docker.LocalDockerEnvironment:πŸ—‘οΈ Removed working directory at /home/sikannan/MICROBOTS_WORKDIR_da35245a \ No newline at end of file diff --git a/docs/getting-started/assets/microbots-execution-flow.svg b/docs/getting-started/assets/microbots-execution-flow.svg new file mode 100644 index 0000000..b8c1a89 --- /dev/null +++ b/docs/getting-started/assets/microbots-execution-flow.svg @@ -0,0 +1,135 @@ + + + + + + + + + + + SETUP + LOOP + RESULT + + + + + 🐍 + Your Script + log_analysis_bot.py + + + + πŸ€– + LogAnalysisBot.run() + task β€’ timeout + + + + 🐳 + Docker Container + code/ read-only β€’ OverlayFS + + + + + 🧠 + LLM + decides next tool call + + + + πŸ“¦ + Container exec + ls β€’ cat β€’ nl β€’ … + + + + + 🧹 + Container Teardown + unmount β€’ remove + + + + πŸ“Š + BotRunResult + root-cause analysis + + + + πŸ–¨οΈ + print(result.result) + your terminal + + + + + + + + + + + task + system prompt + + + + + + + + ⚑ tool-use loop + + + + bounded by timeout + + + + + + + task_done = true + + + + + + diff --git a/docs/getting-started/assets/result-teardown.svg b/docs/getting-started/assets/result-teardown.svg new file mode 100644 index 0000000..3a4bc68 --- /dev/null +++ b/docs/getting-started/assets/result-teardown.svg @@ -0,0 +1,66 @@ + + + + + + + + + + + 🏁 Teardown and return + after the loop ends, the sandbox is cleaned up and the answer comes back to your script + + + + 🧹 + Container Teardown + unmount overlay + remove temp dir Β· stop container + + + + + + + πŸ“Š + BotRunResult + wraps the model's + final root-cause analysis + + + + + + + πŸ–¨οΈ + print(result.result) + the answer you saw + in your terminal + + + + πŸ›‘ cleanup always runs β€” even on error or timeout + diff --git a/docs/getting-started/assets/setup-sandbox.svg b/docs/getting-started/assets/setup-sandbox.svg new file mode 100644 index 0000000..932f001 --- /dev/null +++ b/docs/getting-started/assets/setup-sandbox.svg @@ -0,0 +1,88 @@ + + + + + + + + + + + 🐳 Docker container β€” OverlayFS sandbox + + + + + + + Disposable upper layer + writes land here Β· discarded on exit + + + + πŸ”’ code/ β€” read-only mount + your files, exposed but not writable + + + + πŸ’» Your host filesystem + unreachable through write syscalls + + + + + + sends + + + πŸ“€ First request to the LLM + + + + + + Your task + "Analyze the log file …" + + + packaged with + + + + System prompt + read-only tools Β· role guardrails + + + + + + configured LLM provider + diff --git a/docs/getting-started/assets/tool-use-loop.svg b/docs/getting-started/assets/tool-use-loop.svg new file mode 100644 index 0000000..dde823c --- /dev/null +++ b/docs/getting-started/assets/tool-use-loop.svg @@ -0,0 +1,86 @@ + + + + + + + + + + + πŸ” Agentic tool-use loop + runs until the model is done β€” or a bound is hit + + + + 🧠 + LLM + decides next tool call + + + + πŸ“¦ + Container exec + ls β€’ cat β€’ nl β€’ grep β€’ … + + + + + + tool call (cmd) + + + + + + + stdout / stderr + + + + + ⚑ + + + + + + task_done = true β†’ exit + + + + + + ⏱ timeout cap + + + + πŸ” max iterations + + diff --git a/docs/getting-started/conclusion.md b/docs/getting-started/conclusion.md new file mode 100644 index 0000000..fbb12f5 --- /dev/null +++ b/docs/getting-started/conclusion.md @@ -0,0 +1,36 @@ +# Microbots Execution Flow + +You built a complete Microbots project β€” a sample C application with a deliberate error and a `LogAnalysisBot` run that produced a root-cause analysis without ever modifying your host filesystem. + +## What Just Happened + +`python3 log_analysis_bot.py` triggered the framework to: + +1. **Create a Docker container** with `code/` mounted read-only via OverlayFS. +2. **Send the task** to the LLM with a `LogAnalysisBot` system prompt. +3. **Execute shell commands** inside the container (`ls`, `cat`, `nl`, …) as directed by the LLM. +4. **Return a [`BotRunResult`](../api-reference/microbots/MicroBot.md#microbots.MicroBot.BotRunResult)** containing the root-cause analysis. + +The following diagram shows the end-to-end flow: + +![Microbots execution flow](../images/microbots-execution-flow.svg){ loading=lazy } + +The host filesystem was never writable from the bot. + +## Next Step + +Pick whichever fits your goal: + +- **Debug a Microbots run** β€” Continue to [Configure Logging in Microbots](microbots-logging.md) to turn on Python logging for Microbots and learn how to read those logs. +- **Try a different bot** β€” Browse the [Available Bots](#available-bots) below and jump into the one that fits your use case. + +## Available Bots + +| Bot | Permission | Description | +| -------------------------------------------------------------------- | ---------- | ------------------------------------------------------ | +| [`ReadingBot`](../api-reference/microbots/bot/ReadingBot.md) | Read-only | Reads files and extracts information. | +| [`WritingBot`](../api-reference/microbots/bot/WritingBot.md) | Read-write | Reads and writes files to fix issues or generate code. | +| [`BrowsingBot`](../api-reference/microbots/bot/BrowsingBot.md) | β€” | Browses the web to gather information. | +| [`LogAnalysisBot`](../api-reference/microbots/bot/LogAnalysisBot.md) | Read-only | Analyzes logs for root-cause debugging. | +| [`AgentBoss`](../api-reference/microbots/bot/AgentBoss.md) | β€” | Orchestrates multiple bots for complex tasks. | + diff --git a/docs/getting-started/create-your-first-microbot-project/index.md b/docs/getting-started/create-your-first-microbot-project/index.md new file mode 100644 index 0000000..63e81f5 --- /dev/null +++ b/docs/getting-started/create-your-first-microbot-project/index.md @@ -0,0 +1,89 @@ +# Create Your First Microbot Project + +Create a sample C project with a deliberate compile error. +Generate a build log. Run a `LogAnalysisBot` against it. + +**Requires:** `gcc` (preinstalled on most Linux distributions, or `sudo apt install build-essential`). + +The sample C project files and `LogAnalysisBot` script used in this guide are available in the Microbots examples directory at `examples/microbots_introduction/`. Clone or download the Microbots repository and use those files to follow along. + +## Step 1 β€” Create the Sample Project + +From the root of your `microbots-introduction` project, create a `code/` folder: + +```bash title="Terminal" +mkdir code +``` + +Add a C file with a deliberate syntax error: + +```c title="code/app.c" linenums="1" +--8<-- "docs/examples/microbots_introduction/code/app.c" +``` + +Line 5 is missing the trailing `;` after `return a + b`, so `gcc` will fail. + +## Step 2 β€” Generate the Build Log + +```bash title="Terminal" +cd code +gcc app.c > build.log 2>&1 +cd .. +``` + +`code/build.log` should contain: + +```log title="code/build.log" linenums="1" +app.c: In function β€˜add’: +app.c:5:17: error: expected β€˜;’ before β€˜}’ token + 5 | return a + b + | ^ + | ; + 6 | } + | ~ +``` + +Project layout: + +```text title="Project layout" +microbots-introduction/ +β”œβ”€β”€ .venv +β”œβ”€β”€ .env +└── code/ + β”œβ”€β”€ app.c + └── build.log +``` + +## Step 3 β€” Write the Bot Script + +Create `log_analysis_bot.py` at the project root: + +```python title="log_analysis_bot.py" linenums="1" +--8<-- "docs/examples/microbots_introduction/log_analysis_bot.py" +``` + +The script mounts `code/` **read-only** inside Docker, +Runs `LogAnalysisBot` against `code/build.log` with a 10-minute timeout. +Prints the root-cause analysis from `result.result` + +## Step 4 β€” Run the Bot + +From the project root, with your virtual environment activated: + +```bash title="Terminal" +python3 log_analysis_bot.py +``` + +`print(result.result)` outputs the root-cause analysis: + +```text title="Output" +Root cause identified: The build failed due to a syntax error in +//workdir/code/app.c at line 5. The function add(int a, int b) has +a missing semicolon after the return statement (`return a + b`). +This matches the compiler error in /var/log/build.log: "error: +expected ';' before '}' token". Fix by adding a semicolon: `return a + b;`. +``` + +In this walkthrough, we created buggy code and successfully analyzed it with Microbots. Based on the analysis output, `LogAnalysisBot` correctly identified the bug in the code and explained the fix as well. + +Please read the next article to understand what happens behind the scenes and how to debug Microbots code with logs. Continue with [Microbots Execution Flow](../microbots-execution-flow.md). diff --git a/docs/getting-started/microbots-execution-flow.md b/docs/getting-started/microbots-execution-flow.md new file mode 100644 index 0000000..64b53e3 --- /dev/null +++ b/docs/getting-started/microbots-execution-flow.md @@ -0,0 +1,84 @@ +# Microbots Execution Flow + +You ran your first Microbots example β€” a `LogAnalysisBot` against a sample C application with a deliberate error β€” and got a root-cause analysis without ever modifying your host filesystem. + +## What Just Happened + +When you ran `python3 log_analysis_bot.py`, Microbots quietly orchestrated a sandboxed agentic loop on your behalf. The diagram below shows the full end-to-end flow, organized into three phases that the rest of this page walks through: + +![Microbots execution flow](assets/microbots-execution-flow.svg){ loading=lazy } + +- **SETUP** *(top row)* β€” your script calls `LogAnalysisBot.run()`, which provisions a Docker container with your `code/` directory mounted read-only via OverlayFS, and sends your task plus a system prompt down to the LLM. +- **LOOP** *(middle row)* β€” the LLM and `Container exec` exchange messages back and forth: each turn the LLM picks a shell command, the container runs it, and the output is fed back. The loop exits when the model signals `task_done = true`, and is bounded by your timeout. +- **RESULT** *(bottom row)* β€” the container is torn down (overlay unmounted, working directory removed), the model's analysis is wrapped in a `BotRunResult`, and `print(result.result)` produces the output you saw in your terminal. + +Each phase is explained in detail below, with a focused diagram for the parts that need one. + +### SETUP β€” preparing the sandbox + +![SETUP β€” OverlayFS sandbox and first LLM request](assets/setup-sandbox.svg){ loading=lazy } + +The diagram has two halves. The **left half** shows how your code is sandboxed; the **right half** shows what gets sent to the LLM on the very first turn. + +**Left β€” the OverlayFS sandbox (inside a fresh Docker container):** + +- **Disposable upper layer** *(dashed box on top)* β€” any writes the bot attempts land here and are thrown away when the container exits. +- **`code/` β€” read-only mount** *(solid box below)* β€” your project files are visible to the bot but cannot be modified. +- **Your host filesystem** *(slate panel at the bottom)* β€” sits outside the container and is unreachable through write syscalls. + +**Right β€” the first request to the LLM:** + +- **Your task** *(top box)* β€” the natural-language instruction you passed to `.run(...)`. +- **System prompt** *(bottom box)* β€” the `LogAnalysisBot` role definition that only exposes read-only tools and enforces guardrails. +- Both are **packaged together** and sent to your **configured LLM provider** as the very first message. + +### LOOP β€” the agentic tool-use cycle + +![LOOP β€” agentic tool-use cycle between LLM and container](assets/tool-use-loop.svg){ loading=lazy } + +The diagram shows two boxes connected by a tight cycle, plus two side conditions that govern when the cycle stops. + +- **LLM** *(top box)* β€” on every turn it returns a structured **tool call** (the down-arrow labeled `tool call (cmd)`): a small shell command such as `ls /var/log`, `cat /var/log/build.log`, or `nl -ba build.log`. +- **Container exec** *(bottom box)* β€” executes the command inside the sandbox and sends the **stdout / stderr** back to the model (the up-arrow). The ⚑ badge in the middle marks this `LLM ⇄ Container exec` cycle, which repeats over several iterations until the model has enough evidence. +- **Exit condition** *(yellow badge on the right)* β€” when the model says `task_done = true`, the loop stops. +- **Safety limits** *(red badges on the right)* β€” the loop also stops if it hits your **timeout** or the **max number of tries**, so the bot can't keep running forever. + +### RESULT β€” teardown and return + +![RESULT β€” teardown and return](assets/result-teardown.svg){ loading=lazy } + +The diagram shows three steps from left to right, plus one safety guarantee at the bottom. + +- **Container Teardown** *(left box)* β€” once the loop ends, Microbots **unmounts the OverlayFS overlay**, **removes the temporary working directory**, and **stops the container**. +- **BotRunResult** *(middle box)* β€” the model's final root-cause analysis is wrapped in a [`BotRunResult`](../api-reference/microbots/MicroBot.md#microbots.MicroBot.BotRunResult) object and handed back to your Python code. +- **`print(result.result)`** *(right box)* β€” `result.result` holds the analysis text, which is what you saw printed in your terminal. +- **Cleanup always runs** *(green badge at the bottom)* β€” teardown happens whether the run succeeded, errored out, or hit the timeout, so the container and overlay never leak. + +### Why this matters + +Every run follows this same three-phase flow: a sandboxed container, a read-controlled tool-use loop, and a guaranteed teardown. The goal is simple β€” your code and your machine stay safe, no matter what the model decides to do. + +!!! tip "Read more: Safety-first AI agents" + For a deeper look at how Microbots keeps your machine safe, see the blog post **[Microbots: a safety-first AI agent](../blog/microbots-safety-first-ai-agent.md)**. + +## Next Step + +Pick whichever fits your goal: + +- **Debug a Microbots run** β€” Continue to [Configure Logging in Microbots](microbots-logging.md) to turn on Python logging for Microbots and learn how to read those logs. +- **Try a different bot** β€” Browse the [Available Bots](#available-bots) below and jump into the one that fits your use case. + +## Available Bots + +Similar to `LogAnalysisBot`, you can explore other pre-built bots that ship with Microbots. The table below lists them along with their special capabilities. + +| Bot | Permission | Description | +| -------------------------------------------------------------------- | ---------- | ------------------------------------------------------ | +| [`ReadingBot`](../api-reference/microbots/bot/ReadingBot.md) | Read-only | Reads files and extracts information. | +| [`WritingBot`](../api-reference/microbots/bot/WritingBot.md) | Read-write | Reads and writes files to fix issues or generate code. | +| [`BrowsingBot`](../api-reference/microbots/bot/BrowsingBot.md) | β€” | Browses the web to gather information. | +| [`LogAnalysisBot`](../api-reference/microbots/bot/LogAnalysisBot.md) | Read-only | Analyzes logs for root-cause debugging. | +| [`AgentBoss`](../api-reference/microbots/bot/AgentBoss.md) | β€” | Orchestrates multiple bots for complex tasks. | + +Try them on different use cases β€” and feel free to open a [GitHub issue](https://github.com/microsoft/microbots/issues) if you run into any problems while building your agent. We're happy to help. + diff --git a/docs/getting-started/microbots-logging.md b/docs/getting-started/microbots-logging.md new file mode 100644 index 0000000..c35995b --- /dev/null +++ b/docs/getting-started/microbots-logging.md @@ -0,0 +1,95 @@ +# Configure Logging in Microbots + +Microbots uses standard Python logging, so you can enable logs directly in your bot script and inspect execution details during debugging. + +## 1. Enable Logging in Your Script + +At the **top of your bot script** (before importing `microbots` or creating a bot), add: + +```python +import logging + +logging.basicConfig(level=logging.INFO) # change to logging.DEBUG for deeper diagnostics +``` + +That's it β€” Microbots picks up Python's root logger automatically, so the rest of your script stays unchanged. + +`logging.basicConfig` accepts other parameters too β€” `format`, `datefmt`, `filename`, `filemode`, `handlers`, `stream`, and more β€” that let you customize message format, write logs to a file, or attach custom handlers. See the official Python reference for the full list: [`logging.basicConfig`](https://docs.python.org/3/library/logging.html#logging.basicConfig). + +## 2. Two Levels of Microbots Logging + +Microbots supports two practical logging levels: + +| Level | What it shows | When to use | +| ------- | -------------------------------------------------------------------------------------------- | ----------------------------------------- | +| `INFO` | The bot's steps, LLM thoughts, tool calls, and command outputs. | To follow **what the bot is doing**. | +| `DEBUG` | `INFO` plus internals β€” Docker calls, container execution details, and raw LLM HTTP traffic. | To troubleshoot **why something failed**. | + +## 3. What `INFO` Logging Shows + +Excerpts below are from a real Microbots run, with host paths, container IDs, ports, and endpoint URLs replaced by placeholders like ``, ``, and ``. + +The excerpts are grouped to match the phases of the [execution flow diagram](microbots-execution-flow.md#what-just-happened) you saw in the previous article β€” **SETUP**, **LOOP**, and **RESULT** β€” so each block of logs lines up with a specific part of the picture. + +### SETUP β€” environment setup + +Working directory creation, the host-to-container volume mapping, container startup, and the read-only overlay mount. + +```log +INFO:microbots.environment.local_docker.LocalDockerEnvironment:πŸ—‚οΈ Created working directory at /home/user/MICROBOTS_WORKDIR_ +INFO:microbots.environment.local_docker.LocalDockerEnvironment:πŸ“¦ Volume mapping: /home/user/microbots-introduction/code β†’ /ro/code +INFO:microbots.environment.local_docker.LocalDockerEnvironment:πŸš€ Started container with image microbots/shell_server:latest on host port +INFO:microbots.environment.local_docker.LocalDockerEnvironment:πŸ”’ Set up overlay mount for read-only directory at /workdir/code +INFO:microbots.environment.local_docker.LocalDockerEnvironment:βœ… Successfully copied /home/user/microbots-introduction/code/build.log to container:/var/log +``` + +### LOOP β€” task lifecycle and per-step activity + +`TASK STARTED`, numbered execution steps (`Step-1`, `Step-2`, …), the LLM's thoughts, the tool call, the command output, and finally `TASK COMPLETED`. + +```log +INFO: MicroBot : ℹ️ TASK STARTED : + Analyze the log file `/var/log` +INFO: MicroBot :-------------------- Step-1 -------------------- +INFO: MicroBot : πŸ’­ LLM thoughts: Start by listing the contents of /var/log to identify the relevant log file to analyze. +INFO: MicroBot : ➑️ LLM tool call : "ls -1 /var/log" +INFO: MicroBot : ⬅️ Command output: +ShellCommunicator.log +alternatives.log +build.log +dpkg.log +... +INFO: MicroBot :πŸ”š TASK COMPLETED : +``` + +### LOOP β€” LLM API activity + +One-line `HTTP 200 OK` markers for each request to the model, followed by the parsed LLM response. + +```log +INFO:httpx:HTTP Request: POST https://.openai.azure.com/openai/v1/responses "HTTP/1.1 200 OK" +INFO:microbots.llm.llm:The llm response is {'task_done': False, 'thoughts': 'Start by listing the contents of /var/log to identify the relevant log file to analyze.', 'command': 'ls -1 /var/log'} +``` + +### RESULT β€” teardown and cleanup + +Overlay unmount and cleanup of the working directory once the run completes. + +```log +INFO:microbots.environment.local_docker.LocalDockerEnvironment:πŸ› οΈ Tearing down overlay mount for code +INFO:microbots.environment.local_docker.LocalDockerEnvironment:βœ… Unmounted overlay for code +INFO:microbots.environment.local_docker.LocalDockerEnvironment:πŸ›‘ Removing overlay dirs at //workdir/code and /workdir/overlay/ +INFO:microbots.environment.local_docker.LocalDockerEnvironment:πŸ—‘οΈ Removed overlay directories for code +INFO:microbots.environment.local_docker.LocalDockerEnvironment:πŸ—‘οΈ Removed working directory at /home/user/MICROBOTS_WORKDIR_ +``` + +This view is usually enough to follow what the bot is doing and why. Switch to `DEBUG` only when you need to inspect Docker API calls, raw LLM request/response bodies, or low-level container execution details. + +With logging enabled, every Microbots run is no longer a black box β€” you can see the exact steps, decisions, and commands behind each result. From here, you can build your own bots with confidence, knowing exactly what's happening under the hood. + +## Further Reading + +Now that you can read what Microbots is doing, dive deeper into how it's built: + +- [Microbots Customizability](../blog/microbots-customizability.md) β€” how to tailor bots, tools, and environments to your own use cases. +- [RBAC & Authentication](../blog/rbac-authentication.md) β€” using Azure managed identity and role-based access control with Microbots. \ No newline at end of file diff --git a/docs/getting-started/prerequisites.md b/docs/getting-started/prerequisites.md new file mode 100644 index 0000000..92ac44a --- /dev/null +++ b/docs/getting-started/prerequisites.md @@ -0,0 +1,57 @@ +# Pre-requisites + +In this guide, you will install the two tools every Microbots project needs on your machine. By the end, your laptop will be ready to run any bot safely. + +Install +1. **Python** (the runtime) +2. **Docker** (the sandboxed execution environment) before running any bot. + +!!! note + You only need Python and Docker installed system-wide on your machine. Microbots itself will be installed into a **project-specific Python virtual environment** in the [next article](project-setup-and-installation.md) β€” so nothing gets added to your system Python. + +## Step 1 β€” Installing Python + +Microbots requires **Python 3.10 or later, but below 3.13**. + +!!! info + Python 3.13 compatibility issue is in progress β€” this page will be updated once it lands. + +Pick your OS: + +| OS | Install | +| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Linux** | Ubuntu / Debian:
sudo apt update && sudo apt install python3 python3-pip python3-venv
Fedora:
sudo dnf install python3 python3-pip
| +| **Windows** | Run inside a WSL 2 distribution (e.g. Ubuntu on WSL):
sudo apt update && sudo apt install python3 python3-pip python3-venv
Or use the [official Windows installer](https://www.python.org/downloads/windows/) if you must install on Windows directly. | +| **macOS** | Use [Homebrew](https://brew.sh/):
brew install python@3.12
Or download from [python.org](https://www.python.org/downloads/macos/). | + +Verify the installation β€” run on macOS, WSL on Windows, or Linux: + +```bash title="Terminal" +python3 --version +pip3 --version +``` + +Confirm the version is **at least 3.10 and below 3.13**. + +## Step 2 β€” Installing Docker + +Pick your OS: + +| OS | Install | Notes | +| ----------- | -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| **Linux** | [Docker Engine installation guide](https://docs.docker.com/engine/install/) | After installing, run:
sudo systemctl enable --now docker
sudo usermod -aG docker $USER
newgrp docker
This starts the daemon, adds your user to the `docker` group, and activates it in the current shell. Without it, bots fail with `PermissionError` on `/var/run/docker.sock`. | +| **Windows** | [Docker Desktop for Windows](https://docs.docker.com/desktop/setup/install/windows-install/) | Enable the **WSL 2 backend** during setup, then run Microbots from inside a WSL 2 Linux distribution (e.g. Ubuntu on WSL). Running bot scripts directly from PowerShell or CMD is **not supported**. A dedicated Windows + WSL guide will be added later. | +| **macOS** | [Docker Desktop](https://www.docker.com/products/docker-desktop/) | Install and launch it. No extra commands needed. | + +Verify the installation β€” run on macOS, WSL on Windows, or Linux: + +```bash title="Terminal" +docker --version +docker ps # should succeed without sudo (on Linux) +docker run hello-world +``` + +A "Hello from Docker!" message confirms the daemon is reachable. + +That's it β€” with Python and Docker installed, your machine is ready to run Microbots in an isolated sandbox. Continue with the [Project Setup and Microbots Installation](project-setup-and-installation.md) guide to set up your first project. + diff --git a/docs/getting-started/project-setup-and-installation.md b/docs/getting-started/project-setup-and-installation.md new file mode 100644 index 0000000..4e155b3 --- /dev/null +++ b/docs/getting-started/project-setup-and-installation.md @@ -0,0 +1,43 @@ +# Project Setup and Microbots Installation + +In this guide, you will set up a project folder, install the `microbots` package inside a virtual environment, and configure an LLM provider so your bot has a brain to think with. + +## Step 1 β€” Setting Up the Project Directory + +Create a project folder, activate a virtual environment, and install the `microbots` package: + +```bash title="Terminal" +mkdir microbots-introduction +cd microbots-introduction +python3 -m venv .venv +source .venv/bin/activate +pip install microbots +``` + +When the venv is active, your shell prompt is prefixed with `(.venv)` as below: + +```bash title="Terminal" +(.venv) user@host:~/microbots-introduction$ +``` + +## Step 2 β€” Configuring the LLM Provider + +Microbots supports **Azure OpenAI**, **OpenAI**, **Anthropic**, and **Ollama**. This guide uses Azure OpenAI β€” for the environment variables required by the other providers, see the [Authentication Setup](../advanced/authentication.md) guide. + +Create a `.env` file in the project root: + +```env title=".env" +AZURE_OPENAI_ENDPOINT="https://your-resource-name.openai.azure.com" +AZURE_OPENAI_API_KEY="your-api-key-here" +AZURE_OPENAI_API_VERSION="2025-03-01-preview" +``` + +Replace the placeholders with values from the Azure portal: + +- **`AZURE_OPENAI_ENDPOINT`** β€” the endpoint URL of your Azure OpenAI resource. +- **`AZURE_OPENAI_API_KEY`** β€” a key from the resource's **Keys and Endpoint** page. +- **`AZURE_OPENAI_API_VERSION`** β€” the REST API version your deployment supports. + +Your project is now set up with the `microbots` package installed and an LLM provider configured. Next, you'll create a sample project and run your first bot β€” continue with the [Sample Project Creation and First Run](create-your-first-microbot-project/index.md) guide. + + diff --git a/docs/index.md b/docs/index.md index 7fa858b..f32fd72 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,65 +1,6 @@ -# πŸ€– Microbots +--- +hide: + - navigation +--- -MicroBots is a lightweight, extensible AI agent for code comprehension and controlled file edits. It integrates cleanly into automation pipelines, mounting a target directory with explicit read-only or read/write modes so LLMs can safely inspect, refactor, or generate files with least-privilege access. - -## πŸš€ Quick Start - -### Pre-requisites - -- Docker -- AI LLM Provider and API Key - -### Install - -```bash -pip install microbots -``` - -### Example - -```python -from microbots import WritingBot - -myWritingBot = WritingBot( - model="azure-openai/my-gpt5", - folder_to_mount=str("myReactApp"), -) - -data = myWritingBot.run( - "Fix the build error and make sure the build is successful.", - timeout_in_seconds=600, -) -print(data.results) -``` - -## πŸ€– Available Bots - -| Bot | Description | -|-----|-------------| -| **ReadingBot** | Reads files and extracts information based on instructions (read-only) | -| **WritingBot** | Reads and writes files based on instructions (read/write) | -| **BrowsingBot** | Browses the web to gather information | -| **LogAnalysisBot** | Analyzes logs for debugging | -| **AgentBoss** | Orchestrates multiple bots for complex tasks | - -## βš™οΈ How it works - -![Overall Architecture](images/overall_architecture.png) - -MicroBots creates a containerized environment and mounts the specified directory, restricting permissions to read-only or read/write based on the Bot used. This ensures AI agents operate within defined boundaries, enhancing security and control over code modifications while protecting the local environment. - -## ✨ LLM Support - -Azure OpenAI Models β€” add environment variables in a `.env` file: - -```env -AZURE_OPENAI_ENDPOINT=your-endpoint-url -AZURE_OPENAI_API_KEY=your-api-key -AZURE_OPENAI_API_VERSION=2025-03-01-preview -``` - -## πŸ“š Links - -- [GitHub Repository](https://github.com/microsoft/minions) -- [Contributing Guide](https://github.com/microsoft/minions/blob/main/CONTRIBUTING.md) -- [Code of Conduct](https://github.com/microsoft/minions/blob/main/CODE_OF_CONDUCT.md) +--8<-- "README.md" diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css index cd9e94d..a10efd2 100644 --- a/docs/stylesheets/extra.css +++ b/docs/stylesheets/extra.css @@ -169,3 +169,59 @@ .doc.doc-heading code { cursor: pointer; } + +/* Navigation cards for Previous / Next / Prerequisite links */ +.nav-cards { + display: flex; + gap: 1rem; + flex-wrap: wrap; + margin: 1.5rem 0; +} + +.nav-card { + flex: 1; + min-width: 200px; + border: 1px solid var(--md-default-fg-color--lightest); + border-radius: 8px; + padding: 1rem 1.2rem; + background: var(--md-code-bg-color); + transition: transform 0.2s, box-shadow 0.2s, border-color 0.2s; + text-decoration: none; + color: inherit; + display: block; +} + +.nav-card:hover { + transform: translateY(-2px); + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15); + border-color: var(--md-accent-fg-color, #526cfe); + text-decoration: none; + color: inherit; +} + +.nav-card-label { + font-size: 0.75rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.05em; + color: var(--md-default-fg-color--light); + margin-bottom: 0.3rem; +} + +.nav-card-title { + font-size: 1rem; + font-weight: 700; + color: var(--md-accent-fg-color, #526cfe); +} + +.nav-card--prev { + text-align: left; +} + +.nav-card--next { + text-align: right; +} + +.nav-card--prereq { + border-left: 3px solid var(--md-accent-fg-color, #526cfe); +} diff --git a/mkdocs.yml b/mkdocs.yml index 4028ca9..74cf3e4 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -51,25 +51,40 @@ markdown_extensions: permalink: true - pymdownx.highlight: anchor_linenums: true - - pymdownx.superfences - - pymdownx.snippets + - pymdownx.superfences: + custom_fences: + - name: mermaid + class: mermaid + format: !!python/name:pymdownx.superfences.fence_code_format + - pymdownx.snippets: + base_path: ['.', 'docs'] + check_paths: true - pymdownx.tabbed: alternate_style: true - admonition + - pymdownx.details - tables - attr_list + - md_in_html nav: + - Introduction: index.md - Getting Started: - - Home: index.md - - Guides: - - CopilotBot: copilot-bot.md - - "Authentication Setup": authentication.md - - "Azure Managed Identity & Service Connection Setup": guides/azure-managed-identity-setup.md + - "Pre-requisites": getting-started/prerequisites.md + - "Project Setup and Microbots Installation": getting-started/project-setup-and-installation.md + - "Create Your First Microbot Project": getting-started/create-your-first-microbot-project/index.md + - "Microbots Execution Flow": getting-started/microbots-execution-flow.md + - "Configure Logging in Microbots": getting-started/microbots-logging.md + - Advanced: + - Bots: + - CopilotBot: advanced/bots/copilot-bot.md + - "Authentication Setup": advanced/authentication.md + - "Azure Managed Identity & Service Connection Setup": advanced/azure-managed-identity-setup.md - Tools: - - "Custom Tool Integration Walkthrough": blog/guides/tesseract_ocr_tool_use.md - - Blogs: - - blog/index.md + - "Custom Tool Integration Walkthrough": advanced/tools/tesseract_ocr_tool_use.md + - "Technical Writing Guidelines": advanced/technical-writing-guidelines.md + - Blog: + - "Blog Posts": blog/index.md - "Microbots : Safety First Agentic Workflow": blog/microbots-safety-first-ai-agent.md - "Microbots : Customizability at Every Layer": blog/microbots-customizability.md - "Understanding RBAC & Authentication": blog/rbac-authentication.md