Skip to content

Commit 87bbaac

Browse files
authored
Merge branch 'main' into sdkauto/azure-mgmt-reservations-6362431
2 parents 09b2963 + e92da59 commit 87bbaac

1,498 files changed

Lines changed: 245594 additions & 104889 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/CODEOWNERS

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,10 +112,10 @@
112112
/sdk/textanalytics/ @quentinRobinson @wangyuantao
113113

114114
# PRLabel: %Cognitive - Translator
115-
/sdk/translation/ @jrjrguo @SG-MS
115+
/sdk/translation/ @jrjrguo @zhangeugenia
116116

117117
# ServiceLabel: %Cognitive - Translator
118-
# ServiceOwners: @jrjrguo @SG-MS
118+
# ServiceOwners: @jrjrguo @zhangeugenia
119119

120120
# ServiceLabel: %Communication
121121
# PRLabel: %Communication

.github/workflows/event-processor.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ jobs:
4949
--query value)
5050
5151
echo "::add-mask::$LABEL_SERVICE_API_KEY"
52-
echo "LABEL_SERVICE_API_KEY=$LABEL_SERVICE_API_KEY" >> $GITHUB_ENV
52+
echo "LABEL_SERVICE_API_KEY=$LABEL_SERVICE_API_KEY" >> "$GITHUB_ENV"
5353
5454
APP_CONFIG_ENDPOINT=$(az keyvault secret show \
5555
--vault-name issue-labeler \
@@ -58,7 +58,7 @@ jobs:
5858
--query value)
5959
6060
echo "::add-mask::$APP_CONFIG_ENDPOINT"
61-
echo "APP_CONFIG_ENDPOINT=$APP_CONFIG_ENDPOINT" >> $GITHUB_ENV
61+
echo "APP_CONFIG_ENDPOINT=$APP_CONFIG_ENDPOINT" >> "$GITHUB_ENV"
6262
6363
# To run github-event-processor built from source, for testing purposes, uncomment everything
6464
# in between the Start/End-Build From Source comments and comment everything in between the

.vscode/cspell.json

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,6 @@
9797
"sdk/storage/azure-storage-queue/**",
9898
"sdk/synapse/azure-synapse/**",
9999
"sdk/synapse/azure-synapse-artifacts/**",
100-
"sdk/translation/azure-ai-translation-document/samples/assets/**",
101-
"sdk/translation/azure-ai-translation-document/doc/**",
102-
"sdk/translation/azure-ai-translation-document/tests/glossaries-valid.csv",
103100
"sdk/storage/azure-storage-blob/**",
104101
"sdk/eventhub/azure-eventhub-checkpointstoreblob/azure/eventhub/extensions/checkpointstoreblob/_vendor/**",
105102
"sdk/eventhub/azure-eventhub-checkpointstoreblob-aio/azure/eventhub/extensions/checkpointstoreblobaio/_vendor/**",
@@ -119,15 +116,6 @@
119116
"sdk/monitor/azure-monitor-opentelemetry-exporter/samples/traces/django/sample/db.sqlite3",
120117
"sdk/loadtestservice/azure-developer-loadtesting/**",
121118
"sdk/openai/azure-openai/tests/assets/**",
122-
"sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_serialization.py",
123-
"sdk/translation/azure-ai-translation-text/tests/test_break_sentence.py",
124-
"sdk/translation/azure-ai-translation-text/tests/test_translation.py",
125-
"sdk/translation/azure-ai-translation-text/tests/test_transliteration.py",
126-
"sdk/translation/azure-ai-translation-text/tests/test_break_sentence_async.py",
127-
"sdk/translation/azure-ai-translation-text/tests/test_translation_async.py",
128-
"sdk/translation/azure-ai-translation-text/tests/test_transliteration_async.py",
129-
"sdk/translation/azure-ai-translation-text/azure/ai/translation/text/_model_base.py",
130-
"sdk/translation/test-resources.json",
131119
"eng/**/*.json",
132120
"eng/*.txt",
133121
"eng/tox/tox.ini",

eng/pipelines/templates/jobs/update_pr.yml

Lines changed: 0 additions & 29 deletions
This file was deleted.

eng/tools/azure-sdk-tools/packaging_tools/templates/packaging_files/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pip install azure-identity
2424

2525
### Authentication
2626

27-
By default, [Azure Active Directory](https://aka.ms/awps/aad) token authentication depends on correct configuration of the following environment variables.
27+
By default, [Microsoft Entra](https://learn.microsoft.com/entra/fundamentals/what-is-entra) token authentication depends on correct configuration of the following environment variables.
2828

2929
- `AZURE_CLIENT_ID` for Azure client ID.
3030
- `AZURE_TENANT_ID` for Azure tenant ID.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Release History
2+
3+
## 1.0.0b1 (2026-05-24)
4+
5+
### Features Added
6+
7+
- Initial beta release.
8+
- `load_config(*, config_dir)` — single-call config loader with 4-priority resolution and graceful fallback.
9+
- `load_skills_from_dir(path)` — load skills from a directory on demand (not loaded inline by `load_config`).
10+
- `OptimizationConfig` with instructions, model, temperature, skills, skills_dir, tool_definitions, source, and candidate_id.
11+
- `OptimizationConfig.apply_tool_descriptions(tools)` — patch `__doc__`, `.description`, and `input_model` parameter descriptions on @tool-decorated functions from optimized tool definitions.
12+
- `OptimizationConfig.compose_instructions()` — append skill catalog to instructions.
13+
- `CandidateConfig` — typed representation of the resolver API payload.
14+
- `Skill` — learned skill model (name, description, body).
15+
- 4-priority resolution order:
16+
1. Inline JSON via `OPTIMIZATION_CONFIG` env var.
17+
2. Resolver API via `OPTIMIZATION_CANDIDATE_ID` + `OPTIMIZATION_RESOLVE_ENDPOINT` (endpoint is the full job-scoped URL).
18+
3. Local directory layout (`OPTIMIZATION_LOCAL_DIR` or `config_dir` param, defaults to `.agent_configs/`).
19+
4. No config found → returns `None`.
20+
- Local directory layout: `metadata.yaml` + `instructions.md` + `tools.json` + `skills/` per candidate, with `baseline/` fallback.
21+
- Tool definitions use the OpenAI function-calling list format exclusively.
22+
- Skill loading from `SKILL.md` files with YAML frontmatter.
23+
- Resolver API persists fetched configs and skill files to local directory for offline use.
24+
- Path traversal (zip-slip) protection on skill file downloads from the API.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
Copyright (c) Microsoft Corporation.
2+
3+
MIT License
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
include *.md
2+
include LICENSE
3+
recursive-include tests *.py
4+
recursive-include samples *.py *.md
5+
include azure/__init__.py
6+
include azure/ai/__init__.py
7+
include azure/ai/agentserver/__init__.py
8+
include azure/ai/agentserver/optimization/py.typed
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
# Azure AI Agent Server Optimization client library for Python
2+
3+
The `azure-ai-agentserver-optimization` package provides a drop-in config loader for optimization-ready Azure AI Hosted Agents. A single `load_config()` call resolves optimization parameters (instructions, model, temperature, skills, tool definitions) from multiple sources with graceful fallback — your agent works unchanged when not running under optimization.
4+
5+
## Getting started
6+
7+
### Install the package
8+
9+
```bash
10+
pip install azure-ai-agentserver-optimization
11+
```
12+
13+
### Prerequisites
14+
15+
- Python 3.10 or later
16+
17+
## Key concepts
18+
19+
### Resolution Order
20+
21+
`load_config()` resolves from four sources in order — first match wins:
22+
23+
| Priority | Source | Env vars required | Description |
24+
|----------|--------|-------------------|-------------|
25+
| 1 | **Inline JSON** | `OPTIMIZATION_CONFIG` | Full config as a JSON string. Used by temporary agent versions during evaluation. |
26+
| 2 | **Resolver API** | `OPTIMIZATION_CANDIDATE_ID`, `OPTIMIZATION_RESOLVE_ENDPOINT` | Fetches the candidate config from the remote optimization service and persists it to the local directory. The endpoint should be the full job-scoped URL. |
27+
| 3 | **Local directory** | `OPTIMIZATION_LOCAL_DIR` (optional, defaults to `.agent_configs/`) | Reads from `<local_dir>/<candidate_id>/` or `baseline/` as fallback. |
28+
| 4 | **No config** | *(none)* | Returns `None`. |
29+
30+
When `load_config()` encounters an invalid config source (e.g. malformed JSON env var, unreadable metadata), it raises `ValueError`. Other exceptions (e.g. network errors from the resolver API) propagate to the caller.
31+
32+
### Environment Variables
33+
34+
| Variable | Description |
35+
|----------|-------------|
36+
| `OPTIMIZATION_CONFIG` | Inline JSON config (Priority 1). |
37+
| `OPTIMIZATION_CANDIDATE_ID` | Candidate ID for resolver API or local folder lookup. |
38+
| `OPTIMIZATION_RESOLVE_ENDPOINT` | Full job-scoped URL of the optimization service (e.g. `https://host/api/projects/proj/agents_optimization_job/job-1`). |
39+
| `OPTIMIZATION_LOCAL_DIR` | Path to the local config directory (default: `.agent_configs/`). |
40+
41+
### Local Directory Layout
42+
43+
The local config directory **must** exist with at least a `baseline/` folder before the agent can start to do optimization. When running under optimization, the resolver API (Priority 2) persists candidate configs into the same layout. If a `<candidate_id>/` folder exists it takes precedence; otherwise `baseline/` is used as the fallback.
44+
45+
```
46+
.agent_configs/
47+
├── baseline/ # required — default candidate used at startup
48+
│ ├── metadata.yaml # model, temperature, file pointers
49+
│ ├── instructions.md # system prompt
50+
│ ├── tools.json # tool definitions (OpenAI function-calling list format)
51+
│ └── skills/ # learned skills
52+
│ └── <skill_name>/
53+
│ └── SKILL.md
54+
└── <candidate_id>/ # optional — created by resolver API, same layout as baseline/
55+
├── metadata.yaml
56+
├── instructions.md
57+
├── tools.json
58+
└── skills/
59+
└── <skill_name>/
60+
└── SKILL.md
61+
```
62+
63+
#### `metadata.yaml`
64+
65+
Points to the other files and sets model parameters. All fields are optional:
66+
67+
```yaml
68+
model: gpt-4o
69+
temperature: 0.7
70+
instruction_file: instructions.md
71+
skill_dir: skills
72+
tool_file: tools.json
73+
```
74+
75+
#### `instructions.md`
76+
77+
The system prompt for the agent — plain text or Markdown:
78+
79+
```markdown
80+
You are a travel assistant. Help users search flights, book hotels,
81+
and answer questions about company travel policy.
82+
```
83+
84+
#### `tools.json`
85+
86+
Tool definitions in the OpenAI function-calling list format:
87+
88+
```json
89+
[
90+
{
91+
"type": "function",
92+
"function": {
93+
"name": "lookup_policy",
94+
"description": "Look up the company travel policy.",
95+
"parameters": {
96+
"type": "object",
97+
"properties": {
98+
"dept": {"type": "string", "description": "Department name"}
99+
}
100+
}
101+
}
102+
}
103+
]
104+
```
105+
106+
#### `skills/*/SKILL.md`
107+
108+
Each skill lives in its own subfolder with a `SKILL.md` file. An optional YAML frontmatter block provides the name and description; the rest is the skill body:
109+
110+
```markdown
111+
---
112+
name: budget-checker
113+
description: Check whether a trip is within budget.
114+
---
115+
116+
Compare the trip cost against the department's remaining travel budget
117+
and return APPROVED or DENIED with a reason.
118+
```
119+
120+
### OptimizationConfig Properties
121+
122+
| Property | Type | Description |
123+
|----------|------|-------------|
124+
| `instructions` | `str \| None` | System prompt (optimized or default). |
125+
| `model` | `str \| None` | Model deployment name. |
126+
| `temperature` | `float \| None` | Sampling temperature. |
127+
| `skills` | `list[Skill]` | Learned skills (from inline config). |
128+
| `skills_dir` | `str \| None` | Path to skills directory (for on-demand loading). |
129+
| `tool_definitions` | `list[dict]` | Optimized tool definitions (OpenAI function-calling format). |
130+
| `source` | `str` | Where the config was loaded from. |
131+
| `candidate_id` | `str \| None` | Candidate ID (when resolved via API or local folder). |
132+
| `has_skills` | `bool` | Whether skills are available (inline or via skills_dir). |
133+
134+
### Public API
135+
136+
| Export | Type | Description |
137+
|--------|------|-------------|
138+
| `load_config(*, config_dir)` | function | Load optimization config with 4-priority resolution. |
139+
| `load_skills_from_dir(path)` | function | Load skills from a directory of `SKILL.md` files. |
140+
| `OptimizationConfig` | class | Resolved config with instructions, model, temperature, skills_dir, tool_definitions. |
141+
| `OptimizationConfig.apply_tool_descriptions(tools)` | method | Patch `__doc__`, `.description`, and parameter descriptions on tool functions. |
142+
| `OptimizationConfig.compose_instructions()` | method | Return instructions with skill catalog appended. |
143+
| `CandidateConfig` | class | Typed representation of the resolver API response. |
144+
| `Skill` | class | A learned skill (name, description, body). |
145+
146+
## Examples
147+
148+
### Basic usage
149+
150+
```python
151+
from azure.ai.agentserver.optimization import load_config
152+
153+
config = load_config() # uses .agent_configs/baseline/
154+
config = load_config(config_dir="my_configs") # custom directory
155+
156+
if config is None:
157+
print("No optimization config found")
158+
else:
159+
print(config.instructions) # optimized system prompt
160+
print(config.model) # optimized model name
161+
print(config.temperature) # optimized temperature
162+
print(config.tool_definitions) # optimized tool definitions (list)
163+
print(config.source) # "env:OPTIMIZATION_CONFIG", "api:candidate:abc", "local:...", etc.
164+
```
165+
166+
### Apply optimized tool descriptions
167+
168+
```python
169+
from azure.ai.agentserver.optimization import load_config
170+
171+
config = load_config()
172+
173+
# Your @tool-decorated functions
174+
def search_flights(origin: str, destination: str):
175+
"""Search for flights."""
176+
...
177+
178+
def book_hotel(city: str):
179+
"""Book a hotel room."""
180+
...
181+
182+
# Patches __doc__ and .description on matching tools with optimized descriptions
183+
config.apply_tool_descriptions([search_flights, book_hotel])
184+
```
185+
186+
### Load skills on demand
187+
188+
```python
189+
from pathlib import Path
190+
from azure.ai.agentserver.optimization import load_config, load_skills_from_dir
191+
192+
config = load_config()
193+
194+
# Skills are not loaded inline — load them when needed
195+
if config.skills_dir:
196+
skills = load_skills_from_dir(Path(config.skills_dir))
197+
for skill in skills:
198+
print(f"{skill.name}: {skill.description}")
199+
```
200+
201+
## Troubleshooting
202+
203+
Enable debug logging to see resolution details:
204+
205+
```python
206+
import logging
207+
logging.getLogger("azure.ai.agentserver.optimization").setLevel(logging.DEBUG)
208+
```
209+
210+
Common issues:
211+
- **Config not loading from resolver API** — ensure both env vars are set: `OPTIMIZATION_CANDIDATE_ID` and `OPTIMIZATION_RESOLVE_ENDPOINT`.
212+
- **Local directory not found** — check that `OPTIMIZATION_LOCAL_DIR` points to an existing directory, or ensure `.agent_configs/` exists relative to your main script.
213+
- **`load_config()` returns `None`** — no config source was found; set up a baseline folder or set the appropriate env vars.
214+
215+
## Next steps
216+
217+
- [Azure SDK for Python documentation](https://learn.microsoft.com/azure/developer/python/)
218+
- [Contributing guide](https://github.com/Azure/azure-sdk-for-python/blob/main/CONTRIBUTING.md)
219+
220+
## Contributing
221+
222+
This project welcomes contributions and suggestions. See [CONTRIBUTING.md](https://github.com/Azure/azure-sdk-for-python/blob/main/CONTRIBUTING.md) for details.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
__path__ = __import__("pkgutil").extend_path(__path__, __name__)

0 commit comments

Comments
 (0)