Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .devcontainer/devcontainer-lock.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"features": {
"ghcr.io/azure/azure-dev/azd:latest": {
"version": "0.2.0",
"resolved": "ghcr.io/azure/azure-dev/azd@sha256:01bbec064fcb34f7c8730b3e3c2cc210699e213419664524982268b2910c4f73",
"integrity": "sha256:01bbec064fcb34f7c8730b3e3c2cc210699e213419664524982268b2910c4f73"
},
"ghcr.io/devcontainers/features/azure-cli:1": {
"version": "1.2.9",
"resolved": "ghcr.io/devcontainers/features/azure-cli@sha256:4549175fbfd3475d1d62e82f6e5425d03954a6ae06027b2515b0ba41a8206417",
"integrity": "sha256:4549175fbfd3475d1d62e82f6e5425d03954a6ae06027b2515b0ba41a8206417"
},
"ghcr.io/devcontainers/features/docker-in-docker:2": {
"version": "2.16.1",
"resolved": "ghcr.io/devcontainers/features/docker-in-docker@sha256:ce078b7bf7d9ef3bcb9813b32103795d8d72172446890b64772cbe1dec6baafd",
"integrity": "sha256:ce078b7bf7d9ef3bcb9813b32103795d8d72172446890b64772cbe1dec6baafd"
},
"ghcr.io/devcontainers/features/node:1": {
"version": "1.7.1",
"resolved": "ghcr.io/devcontainers/features/node@sha256:8c0de46939b61958041700ee89e3493f3b2e4131a06dc46b4d9423427d06e5f6",
"integrity": "sha256:8c0de46939b61958041700ee89e3493f3b2e4131a06dc46b4d9423427d06e5f6"
},
"ghcr.io/jsburckhardt/devcontainer-features/uv:1": {
"version": "1.0.0",
"resolved": "ghcr.io/jsburckhardt/devcontainer-features/uv@sha256:542a0bc2203205b3c696de650ba862f280b20af3543493cc232edd9ac35791f7",
"integrity": "sha256:542a0bc2203205b3c696de650ba862f280b20af3543493cc232edd9ac35791f7"
}
}
}
14 changes: 13 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -472,4 +472,16 @@ data/sample_code/
*.local*.bicepparam
*.local*.parameters.json
# Local debug/ops scripts (not for repo)
scripts/
scripts/
# Local debug/log dumps (terminal output captures, plan inspections, image scratch)
be*.json
be*.txt
backend_logs*.txt
mcp*.json
mcp*.txt
mcp_logs*.txt
plan_*.json
plan_*.txt
plan.json
upload_resp.json
generated_image.png
1 change: 1 addition & 0 deletions .last_backend_tag
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
rev-20260507113558
24 changes: 24 additions & 0 deletions azure.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,31 @@ metadata:
template: multi-agent-custom-automation-engine-solution-accelerator@1.0
requiredVersions:
azd: '>= 1.18.0'
services:
backend:
project: ./src/backend
language: docker
host: containerapp
docker:
remoteBuild: true
mcp:
project: ./src/mcp_server
language: docker
host: containerapp
docker:
remoteBuild: true
hooks:
postprovision:
windows:
run: ./infra/scripts/Deploy-AI-Models.ps1
shell: pwsh
interactive: true
continueOnError: false
posix:
run: ./infra/scripts/deploy-ai-models.sh
shell: sh
interactive: true
continueOnError: false
postdeploy:
windows:
run: |
Expand Down
1 change: 1 addition & 0 deletions body.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"model":"gpt-4.1","input":"hi"}
78 changes: 78 additions & 0 deletions content_packs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
# Content Packs

Optional, drop-in extensions to the Multi-Agent Custom Automation Engine. A pack
ships everything needed to add a domain-specific agent team **without touching
core code**.

The core solution works fine when this folder is empty or absent.

> 💡 **Looking for a starting point?** See [example_pack/](example_pack/README.md)
> — a minimal, fully-working pack that demonstrates the team config, AI Search
> index, and blob upload features. Copy that folder and edit it.

## Convention

```
content_packs/
└── <pack_name>/
├── pack.json # optional — declares pack-level Azure resources
├── agent_teams/
│ └── <pack_name>.json # required — uploaded automatically on deploy
├── datasets/ # optional — sample data your tools/scripts use
│ ├── data/*.csv
│ └── images/*.png
├── scripts/ # optional — pack-local one-off utilities
└── mcp_tools/ # optional — pack-specific MCP services (manual wiring today)
```

`<pack_name>` should be lowercase snake_case (e.g. `content_gen`, `legal_review`).

## How packs are picked up

During deployment, [Selecting-Team-Config-And-Data.ps1](../infra/scripts/Selecting-Team-Config-And-Data.ps1)
discovers packs and provisions everything they declare:

1. **Team configs** — [upload_team_config.py](../infra/scripts/upload_team_config.py)
globs `content_packs/*/agent_teams/*.json`, picks a deterministic UUID
(`team_id` in the JSON if it's a UUID, otherwise `uuid5("…aaaa", "<pack>")`),
and POSTs each to `/api/v4/upload_team_config`.
2. **Pack-level resources** — [provision_content_pack.py](../infra/scripts/provision_content_pack.py)
reads each `pack.json` and provisions Azure resources it declares
(currently: AI Search indexes built from CSVs, and raw-file blob uploads).

This means uploading a new pack is just: drop the folder in, redeploy.

## Manifest schema (`pack.json`)

```jsonc
{
"name": "<pack>",
"description": "...",
"search_indexes": [ // optional
{
"index_name": "<index>",
"csv_path": "datasets/data/<file>.csv",
"key_field": "id", // optional, default "id"
"title_field": "<column>" // optional, default first non-key column
}
],
"blob_uploads": [ // optional
{
"container": "<container>",
"source": "datasets/data", // file or directory inside the pack
"pattern": "*.csv" // optional, default "*"
}
]
}
```

Both lists are optional. A pack with no `pack.json` will still have its team
configs uploaded — the manifest only adds Azure-side provisioning.

## Removing a pack

Delete the pack folder. The team configs it previously uploaded remain in
Cosmos until you delete them via `DELETE /api/v4/team_configs/{team_id}` (the
deterministic UUID is `uuid5("00000000-0000-0000-0000-00000000aaaa", "<pack_name>")`).
Search indexes and blob containers created from the manifest are also left in
place — clean them up with `az search` / `az storage` if no longer needed.
Loading
Loading