Skip to content
Draft
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
3 changes: 2 additions & 1 deletion docs/front-matter-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ For capabilities (MCP, skills, tools):

| Level | Required Properties | Optional Properties |
|-------|-------------------|-------------------|
| **Global** (`agents.config.yaml`) | None (entire file is optional) | `mcp`, `system_tools`, `model`, `timeout`, `tools` |
| **Global** (`agents.config.yaml`) | None (entire file is optional) | `version`, `mcp`, `system_tools`, `model`, `timeout`, `tools` |
| **Agent** (`.agent.md` front matter) | `name`, `description`, `trigger`* | `debug`, `model`, `timeout`, `system_tools`, `mcp`, `skills`, `tools`, `input_schema`, `response_schema`, `response_example`, `metadata` |


Expand All @@ -57,6 +57,7 @@ Optional file in the root directory that defines infrastructure and capabilities
**Required properties:** None (entire file is optional)

**Supported properties:**
- `version` — Optional string identifying the configuration schema/version (e.g., `"1.0"`). Used for tracking changes to the global config over time. Not validated against any specific value; treat it as informational metadata.
- `mcp` — Array of MCP server names (servers must be defined in `mcp.json`)
- `system_tools` — Object containing system-level tools configuration
- `execute_in_sessions` — Object with code execution sandbox configuration
Expand Down
1 change: 1 addition & 0 deletions samples/basic-chat/src/agents.config.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Global configuration for all agents in this function app
version: "1.0"

# Shared infrastructure
system_tools:
Expand Down
1 change: 1 addition & 0 deletions samples/daily-azure-report/src/agents.config.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Global configuration for all agents in this function app
version: "1.0"

# Shared infrastructure - Email capabilities via Office 365 connector
system_tools:
Expand Down
1 change: 1 addition & 0 deletions samples/daily-tech-news-email/src/agents.config.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Global configuration for all agents in this function app
version: "1.0"

# Shared infrastructure
system_tools:
Expand Down
13 changes: 13 additions & 0 deletions src/azure_functions_agents/config/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,25 @@ class GlobalConfig(BaseModel):

model_config = ConfigDict(extra="forbid")

version: str | None = None
mcp: list[str] = Field(default_factory=list)
system_tools: SystemToolsConfig | None = None
model: str | None = None
timeout: float | None = None
tools: ToolsFilter | None = None

@field_validator("version", mode="before")
@classmethod
def _coerce_version(cls, value: Any) -> Any:
# Accept numeric versions like `1` or `1.0` in YAML and store as string.
if value is None or isinstance(value, str):
return value
if isinstance(value, bool):
raise ValueError("version must be a string")
if isinstance(value, (int, float)):
return str(value)
raise ValueError("version must be a string")


class AgentSpec(BaseModel):
"""Raw per-agent specification parsed from frontmatter plus markdown body."""
Expand Down
24 changes: 24 additions & 0 deletions tests/test_config_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def test_load_global_config_leaves_unset_placeholders_literal(tmp_path: Path) ->
def test_load_global_config_missing_returns_empty(tmp_path: Path) -> None:
assert load_global_config(tmp_path) == load_global_config(tmp_path)
assert load_global_config(tmp_path).model_dump() == {
"version": None,
"mcp": [],
"system_tools": None,
"model": None,
Expand All @@ -81,6 +82,29 @@ def test_load_global_config_malformed_yaml(tmp_path: Path) -> None:
load_global_config(tmp_path)


def test_load_global_config_with_version(tmp_path: Path) -> None:
(tmp_path / "agents.config.yaml").write_text(
textwrap.dedent(
"""
version: "1.0"
model: gpt-4o
"""
).strip(),
encoding="utf-8",
)

config = load_global_config(tmp_path)
assert config.version == "1.0"
assert config.model == "gpt-4o"


def test_load_global_config_version_coerces_numeric(tmp_path: Path) -> None:
(tmp_path / "agents.config.yaml").write_text("version: 1\n", encoding="utf-8")

config = load_global_config(tmp_path)
assert config.version == "1"


def test_load_agent_specs_reads_files_and_substitutes(
monkeypatch: pytest.MonkeyPatch,
tmp_path: Path,
Expand Down