An updated version of the original AI-Employee app. Now running on MS Agents SDK.
Build the app:
docker build -t ai-employee .
Run the app:
docker run --rm -p 8080:80 --env-file .env ai-employee
Besides plain-language requests, the bot understands these commands (type /help in chat for the same list):
| Command | What it does |
|---|---|
/help | Capability overview, command list and Microsoft 365 sign-in status |
login / /login | Returns the Microsoft 365 OAuth link (mail, calendar, OneDrive access) |
refresh / /refresh | Wipes the conversation history and resets the code sandbox |
/schedule <what & when> | Schedules a task in natural language (cron-backed) |
/tasks | Lists the user's scheduled tasks, briefings and watches |
/projects | Lists saved projects/files (OneDrive on Teams, object storage elsewhere) |
/memory | Shows the contents of the user's GLOBAL_MEMORY.md |
/briefing [HH:MM] [off] | Opt-in daily morning briefing (UTC, default 08:00): today's calendar, inbox highlights and due tasks, delivered proactively |
/watch [emails|meetings] [on|off] | Opt-in proactive intelligence: important new emails are summarized with a suggested draft reply; meetings get a prep brief ~15 minutes ahead. Watches poll MS Graph every 5 minutes through the scheduled-task loop |
/quit, /save | Inside code mode: leave the coder session / save the project. Other coder-native commands (e.g. /rewind) pass through to the coder service |
/briefing and /watch require the user to login first, and are stored as recurring rows in the scheduled-tasks table, so they survive restarts and work across multiple replicas.
| Variable | Required | Default | Description |
|---|---|---|---|
MODEL_PROVIDER | Yes | "" | The provider of the LLM (accepts: AWS) |
MODEL_NAME | Yes | "" | Bedrock model ID (e.g. global.anthropic.claude-sonnet-4-5-20250929-v1:0) |
MODEL_DEPLOYMENT_NAME | Yes | "" | AWS access key ID |
MODEL_API_KEY | Yes | "" | AWS secret access key |
MODEL_VERSION | Yes | "" | AWS region (e.g. us-east-2) |
MODEL_MAX_TOKENS | No | 8000 | Maximum tokens per LLM response |
MODEL_TIMEOUT | No | 300 | LLM request timeout in seconds |
MODEL_MEMORY_TOKENS | No | 8000 | Token budget for the agent's conversation memory buffer |
STREAMING | No | false | Stream agent responses to the Teams client in chunks |
| Variable | Required | Default | Description |
|---|---|---|---|
GEMINI_API_KEY | Yes | "" | Google Gemini API key |
GEMINI_MODEL | No | "" | Gemini model name (e.g. gemini-2.5-flash) |
GOOGLE_GENAI_USE_VERTEXAI | No | true | If true Google Gemini requests will be routed through the Vertex API. It's recommended that this variable is included and set to false |
The app's persistent storage (tables + object storage) can be hosted on Azure or AWS. CLOUD_PROVIDER selects the backend; everything else behaves identically. This is independent of MODEL_PROVIDER, which only selects the LLM backend.
| Variable | Required | Default | Description |
|---|---|---|---|
CLOUD_PROVIDER | No | azure | azure uses Azure Table Storage + Blob Storage; aws uses DynamoDB + S3 |
Used when CLOUD_PROVIDER=azure (the default) to persist user OAuth tokens, session data, scheduled tasks, conversation snapshots and user projects.
| Variable | Required | Default | Description |
|---|---|---|---|
USER_STORAGE_ACCOUNT_NAME | Yes | "" | Azure Storage account name |
USER_STORAGE_SAS_TOKEN | Yes | "" | SAS token with read/write access to the table |
USER_STORAGE_TABLE_NAME | Yes | "" | Table name (e.g. AIEmployeeUsers) |
TASK_STORAGE_TABLE_NAME | No | scheduledtasks | Table where scheduled tasks and conversation references for proactive messaging are stored |
BLOB_CONTAINER_NAME | No | useruploads | Blob container where user files/projects live on non-Teams channels |
CONVERSATION_CONTAINER_NAME | No | conversations | Blob container (same storage account) where per-user conversation snapshots are persisted. Conversations survive restarts and idle timeouts; typing refresh wipes a user's history. When a conversation outgrows MODEL_MEMORY_TOKENS, the oldest messages are compacted into a rolling summary instead of being truncated, so MODEL_MEMORY_TOKENS can be raised safely. |
Used when CLOUD_PROVIDER=aws. The table-name variables above (USER_STORAGE_TABLE_NAME, TASK_STORAGE_TABLE_NAME) become DynamoDB table names, and the container-name variables (BLOB_CONTAINER_NAME, CONVERSATION_CONTAINER_NAME) become S3 bucket names — S3 bucket names are globally unique, so set them to buckets you own. Tables and buckets are created automatically if the credentials allow it. USER_STORAGE_ACCOUNT_NAME/USER_STORAGE_SAS_TOKEN are ignored.
| Variable | Required | Default | Description |
|---|---|---|---|
AWS_REGION | Yes | us-east-1 | Region for DynamoDB and S3 |
AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY | No | "" | Explicit credentials; omit to use the standard AWS chain (IAM role, instance profile, ...). Needs DynamoDB + S3 read/write (and CreateTable/CreateBucket for auto-provisioning) |
AWS_ENDPOINT_URL | No | "" | Override endpoint (e.g. LocalStack) for local testing |
| Variable | Required | Default | Description |
|---|---|---|---|
SANDBOX_URL | No | http://host.docker.internal:8000 | Code sandbox API endpoint |
CODER_TIMEOUT | No | 3600 | Max seconds for non-streaming coder service calls (/session/start, /session/save, /session/stop, one-shot /session/osp tasks). The interactive /session/prompt stream is unbounded. |
BROWSER_USE_HOST | No | http://localhost:8080 | Public-facing base URL for NoVNC browser session links sent to users |
BROWSER_USER_REPLY_TIMEOUT | No | 900 | Seconds the browser agent's ask_user_for_help action waits for the user's chat reply before continuing without them |
REDIRECT_URI | No | http://localhost:8080/callback | OAuth redirect URI used for granting permissions to MS Graph services |
| Variable | Required | Default | Description |
|---|---|---|---|
ENCRYPTION_KEY | Yes | "" | 64-char hex key used to encrypt and decrypt refresh tokens. |
VNC_SECRET_KEY | No | change-me-in-production | Secret key used to authorize user's Broser-Use session. Change this in production. |
INTERNAL_AUTH_SECRET | No | change-me-in-production | Shared secret between the bot and server for proactive messaging. Change this in production. |
When NLSQL_API_KEY is set, users on any channel other than msteams, directline, and webchat (e.g. Telegram) must authorize before the assistant serves them: their first message must be the unique access code generated on the NLSQL platform. The code is validated via POST https://api.nlsql.com/save_skype_id; on success the user's ID is stored in the AllowedUsers partition of the user-data table and they are never asked again. Until then the bot keeps asking for the code. When NLSQL_API_KEY is unset the gate is disabled.
| Variable | Required | Default | Description |
|---|---|---|---|
NLSQL_API_KEY | No | "" | NLSQL platform API key. Setting it activates the channel authorization gate. |
| Variable | Required | Default | Description |
|---|---|---|---|
DL_TOOL_<tool name> | No | None | The description of the given Direct Line tool Note: <tool name> should be replaced by the desired tool name (the LLM will see this) and should match the tool name in the DL_SECRET variable. |
DL_SECRET_<tool name> | No | None | The secret of the given Direct Line tool Note: The <tool name> should match the tool name given above with its corresponding description. |
connections__serviceConnection__settings__clientId | Yes | "" | Azure AD app (client) ID |
connections__serviceConnection__settings__clientSecret | Yes | "" | Azure AD client secret |
connections__serviceConnection__settings__tenantId | Yes | "" | Azure AD tenant ID |
GRAPH_API_ID | No | value of connections__serviceConnection__settings__clientId | App registration ID for OAuth flow + Graph API access |
GRAPH_API_SECRET | No | value of connections__serviceConnection__settings__clientSecret | App secret for OAuth flow + Graph API access |
DEBUG | No | false | Enable verbose debug logging across all services |
To generate the app secrets you can run these commands in your CLI:
ENCRYPTION_KEY:
python -c "import secrets; print(secrets.token_hex(32))"
VNC_SECRET_KEY & INTERNAL_AUTH_SECRET
python -c "import secrets; print(secrets.token_urlsafe(32))"
Content type
Image
Digest
sha256:8c61fadbf…
Size
1.3 GB
Last updated
about 2 months ago
docker pull denissa4/ai-employee-dev