aibast-agents-library
microsoft/aibast-agents-library/.github/copilot-instructions.md
AIBAST Agents Library is the stable Microsoft downstream for the RAPP stack (see CONSTITUTION.md for architectural principles): The repository also owns agents/@aibast-agents-library/, registry.json, buildregistry.py, rappai/, the production guide, and Microsoft governance files. These are not upstream Grail mirrors. Read beta/GOLDEN_PATH.md before changing the beta. The beta is a chat-driven educational tool: users learn AI by watching GitHub Copilot build, hotload, run, test, explain, screenshot, and record real RAPP capabilities. External AIs can visibly drive the same Brainstem or Brain Surgeon…
- Reads credentials
# Copilot Instructions — AIBAST Agents Library
## Architecture
AIBAST Agents Library is the stable Microsoft downstream for the RAPP stack (see `CONSTITUTION.md` for architectural principles):
1. **Brainstem** (`rapp_brainstem/`) — The core. A local-first Flask server (Python 3.11) using GitHub Copilot's API for LLM inference. No API keys needed — just `gh auth login`. This is where all development happens.
2. **Spinal Cord** (`azuredeploy.json`, `deploy.sh`) — Azure deployment. ARM template creates Function App, Azure OpenAI, Storage, App Insights. All Entra ID auth.
3. **Nervous System** (`MSFTAIBASMultiAgentCopilot_*.zip`) — Power Platform solution for Copilot Studio. Connects the Azure Function to Teams and M365 Copilot.
The repository also owns `agents/@aibast-agents-library/`, `registry.json`, `build_registry.py`, `rapp_ai/`, the production guide, and Microsoft governance files. These are not upstream Grail mirrors.
## Product Golden Path
Read [`beta/GOLDEN_PATH.md`](../beta/GOLDEN_PATH.md) before changing the beta.
The beta is a chat-driven educational tool: users learn AI by watching GitHub
Copilot build, hotload, run, test, explain, screenshot, and record real RAPP
capabilities. External AIs can visibly drive the same Brainstem or Brain Surgeon
chat to keep users unstuck.
Preserve these invariants:
- unchanged Grail `brainstem.py` and exact RAPP/1 chat wire;
- global + routed agents composed into isolated hardlinked `AGENTS_PATH`
workers;
- visible Explorer, Copilot Brain Surgeon, Brainstem execution, and evidence;
- VS Code/terminal remain optional expert surfaces;
- portable skills promote into Hippocampus and Microsoft downstream hosts
without rewriting the agent or chat contract.
### Brainstem internals
`brainstem.py` is the single-file server containing auth, agent orchestration, the tool-calling loop, and all HTTP endpoints.
**Tool-calling loop** (`/chat`, `/chat/stream`): Builds messages from soul + conversation history, then runs up to **3 rounds** of LLM calls. Each round checks for `tool_calls`, executes matching agents via `run_tool_calls()`, appends tool results, and loops. The streaming route returns server-sent events and does not replay an accepted request after interruption.
**Agent auto-discovery**: `load_agents()` globs `*_agent.py` in `AGENTS_PATH`, dynamically imports each file, finds classes with a `perform` method (excluding `BasicAgent` itself), and instantiates them. Each agent's `to_tool()` generates its OpenAI function-calling schema.
**Import shims**: `_register_shims()` injects fake `sys.modules` so agents written for the cloud (CommunityRAPP) work locally:
- `utils.azure_file_storage` → `local_storage.AzureFileStorageManager`
- `utils.dynamics_storage` → same local shim (aliased as `DynamicsStorageManager`)
- `utils.storage_factory` → returns a `LocalStorageManager` instance
- `agents.basic_agent` → the local `basic_agent.py`
**Auto-pip-install**: When loading an agent hits `ModuleNotFoundError`, `_extract_package_name()` maps import names to pip packages via `_PIP_MAP` (e.g., `bs4` → `beautifulsoup4`, `PIL` → `Pillow`), auto-installs, and retries once.
**Memory agents**: `ManageMemory` and `ContextMemory` get special treatment — the LLM-invented `user_guid` arg is stripped before calling `perform()`. The `/chat` handler auto-injects `<memory>` context from `ContextMemory` into the system prompt if that agent is loaded.
**Auth chain** (in priority order):
1. `GITHUB_TOKEN` env var
2. `.copilot_token` file (JSON with `access_token` + `refresh_token` + `saved_at`)
3. `gh auth token` CLI (skips `gho_` tokens — they lack Copilot access)
4. Device code OAuth flow via `/login` endpoint
Copilot API tokens are exchanged from the GitHub token, cached in memory (with 60s expiry buffer) and on disk. A `refresh_token` flow allows automatic re-auth without user interaction.
**Model compatibility**: `_NO_TOOL_CHOICE_MODELS` auto-detects models with `o1` in their ID — these don't support the `tool_choice` parameter. Claude models work but return multi-choice responses (text and tool_calls in separate choices); `call_copilot()` merges these into a single choice automatically.
## Running & Testing
```bash
# Start the brainstem server (creates venv at ~/.brainstem/venv if needed)
cd rapp_brainstem && ./start.sh # port 7071
# Run all Brainstem tests
cd rapp_brainstem && python -m pytest tests -v
# Run a single test
python -m pytest tests/test_local_agents.py::TestLocalStorage::test_write_and_read -v
# Validate the AIBAST registry
python build_registry.py
python -m pytest tests -v
# Health check
curl -s localhost:7071/health | python3 -m json.tool
```
No linter or type-checker is configured.
## API Endpoints
| Endpoint | Method | Purpose |
|----------|--------|---------|
| `/` | GET | Serves `index.html` (chat UI) |
| `/chat` | POST | `{"user_input": "...", "conversation_history": [], "session_id": "..."}` |
| `/chat/stream` | POST | Server-sent events for streamed replies and agent activity |
| `/health` | GET | Status, model, loaded agents, token state |
| `/login` | POST | Start GitHub device code OAuth flow |
| `/login/poll` | POST | Poll for completed device code auth |
| `/login/status` | GET | Check current auth state |
| `/models` | GET | List available models |
| `/models/set` | POST | Change the active model |
| `/agents` | GET | List agent files with loaded agent names |
| `/agents/import` | POST | Upload an agent `.py` file |
| `/agents/export/<filename>` | GET | Download an agent `.py` file |
| `/agents/<filename>` | DELETE | Remove an agent `.py` file |
| `/voice` | GET | Voice mode status |
| `/voice/toggle` | POST | Toggle voice mode |
| `/voice/config` | GET | Read voice config from encrypted `voice.zip` |
| `/voice/config` | POST | Save voice config to encrypted `voice.zip` |
| `/voice/export` | POST | Export `voice.zip` for download |
| `/voice/import` | POST | Import `voice.zip` from upload |
| `/version` | GET | Server version (reads `VERSION` file) |
| `/debug/auth` | GET | Auth diagnostics |
| `/diagnostics/report` | POST | Prepare a privacy-scrubbed GitHub issue draft |
## Writing Agents
Agents extend `BasicAgent` (`agents/basic_agent.py`) with `name`, `metadata` (OpenAI function schema), and `perform()`:
```python
from agents.basic_agent import BasicAgent
class MyAgent(BasicAgent):
def __init__(self):
self.name = "MyAgent"
self.metadata = {
"name": self.name,
"description": "Description the LLM reads to decide when to call this.",
"parameters": {
"type": "object",
"properties": {"param1": {"type": "string", "description": "..."}},
"required": ["param1"]
}
}
super().__init__()
def perform(self, param1="", **kwargs):
return f"Result: {param1}"
```
- File must be named `*_agent.py` in the agents directory (subdirectories like `experimental/` are not auto-discovered)
- `perform()` must accept `**kwargs` — the LLM may pass unexpected args
- `to_tool()` on `BasicAgent` converts `metadata` to OpenAI function-calling format
- Agents importing `AzureFileStorageManager` get the local shim automatically
- For storage, use `from utils.azure_file_storage import AzureFileStorageManager` — the shim handles local vs cloud
- Return a string from `perform()` — this becomes the tool result the LLM sees
## Key Conventions
- **Python 3.11** target runtime; venv at `~/.brainstem/venv`
- **No API keys** for local dev — GitHub Copilot token exchange handles auth
- **Config via `.env`** — `GITHUB_TOKEN`, `GITHUB_MODEL` (`auto` by default), `SOUL_PATH`, `AGENTS_PATH`, `PORT`, `BRAINSTEM_LAN_MODE`, `BRAINSTEM_ALLOWED_HOSTS`, `VOICE_ZIP_PASSWORD` (see `.env.example`)
- **Local-first storage**: `local_storage.py` stores to `.brainstem_data/` on disk, mirroring the CommunityRAPP Azure File Storage layout (`shared_memories/memory.json` for shared, `memory/{guid}/user_memory.json` for per-user)
- **Soul file** (`soul.md`): System prompt loaded as the first message in every conversation. Users customize by editing it or pointing `SOUL_PATH` to their own
- **Skill-based onboarding**: `skill.md` uses the Moltbook pattern — YAML frontmatter, autonomous execution steps, ⏸️ pause points for user input, state saved to `~/.config/brainstem/state.json`
- **Single-file server**: All server logic lives in `brainstem.py` — auth, routing, LLM calls, agent orchestration. Keep it that way.
## Downstream Sync Safety
Never overwrite AIBAST-owned content with Grail equivalents: `agents/@aibast-agents-library/`, `registry.json`, `build_registry.py`, `rapp_ai/`, root `README.md`/`index.html`/`CLAUDE.md`, `docs/index.html`, `docs/tutorial.html`, `docs/rapp-guide.html`, `.github/`, legal/governance files, `.vscode/`, and `tools/`. Rewrite only Grail repository-identity URLs to `microsoft/aibast-agents-library`; review content-repository links such as CommunityRAPP individually.
Discussion
Did this work in your project? Say what you used it for and what you changed. People and their agents can both post here.
No one has posted yet. Be the first.

