Python: Introducing support for declarative yaml spec (#2002)

* first work on declarative

* initial version of the declarative support

* fix tests and mypy

* fix parameters of functiontool

* slight logic improvement

* remove path until merge

* updates from comments

* create dispatcher and spec type, json_schema method

* fix mypy, skipping model

* updated lock

* fixed declarative tests and renamed some other test files

* refined loader

* updated lock

* fix mypy

* added readme to samples folder

* fixes from review

* undid test file rename
This commit is contained in:
Eduard van Valkenburg
2025-11-19 17:33:02 +01:00
committed by GitHub
Unverified
parent d2d0f46e15
commit 92df9e14bf
35 changed files with 3924 additions and 6 deletions
@@ -589,7 +589,7 @@ class ChatAgent(BaseAgent):
chat_message_store_factory: Callable[[], ChatMessageStoreProtocol] | None = None,
context_providers: ContextProvider | list[ContextProvider] | AggregateContextProvider | None = None,
middleware: Middleware | list[Middleware] | None = None,
# chat option params
# chat options
allow_multiple_tool_calls: bool | None = None,
conversation_id: str | None = None,
frequency_penalty: float | None = None,
@@ -214,6 +214,7 @@ def _merge_chat_options(
*,
base_chat_options: ChatOptions | Any | None,
model_id: str | None = None,
allow_multiple_tool_calls: bool | None = None,
frequency_penalty: float | None = None,
logit_bias: dict[str | int, float] | None = None,
max_tokens: int | None = None,
@@ -239,6 +240,7 @@ def _merge_chat_options(
Keyword Args:
base_chat_options: Optional base ChatOptions to merge with direct parameters.
model_id: The model_id to use for the agent.
allow_multiple_tool_calls: Whether to allow multiple tool calls in a single response.
frequency_penalty: The frequency penalty to use.
logit_bias: The logit bias to use.
max_tokens: The maximum number of tokens to generate.
@@ -270,6 +272,7 @@ def _merge_chat_options(
return base_chat_options & ChatOptions(
model_id=model_id,
allow_multiple_tool_calls=allow_multiple_tool_calls,
frequency_penalty=frequency_penalty,
logit_bias=logit_bias,
max_tokens=max_tokens,
@@ -485,6 +488,7 @@ class BaseChatClient(SerializationMixin, ABC):
self,
messages: str | ChatMessage | list[str] | list[ChatMessage],
*,
allow_multiple_tool_calls: bool | None = None,
frequency_penalty: float | None = None,
logit_bias: dict[str | int, float] | None = None,
max_tokens: int | None = None,
@@ -517,6 +521,7 @@ class BaseChatClient(SerializationMixin, ABC):
messages: The message or messages to send to the model.
Keyword Args:
allow_multiple_tool_calls: Whether to allow multiple tool calls in a single response.
frequency_penalty: The frequency penalty to use.
logit_bias: The logit bias to use.
max_tokens: The maximum number of tokens to generate.
@@ -545,6 +550,7 @@ class BaseChatClient(SerializationMixin, ABC):
chat_options = _merge_chat_options(
base_chat_options=kwargs.pop("chat_options", None),
model_id=model_id,
allow_multiple_tool_calls=allow_multiple_tool_calls,
frequency_penalty=frequency_penalty,
logit_bias=logit_bias,
max_tokens=max_tokens,
@@ -580,6 +586,7 @@ class BaseChatClient(SerializationMixin, ABC):
self,
messages: str | ChatMessage | list[str] | list[ChatMessage],
*,
allow_multiple_tool_calls: bool | None = None,
frequency_penalty: float | None = None,
logit_bias: dict[str | int, float] | None = None,
max_tokens: int | None = None,
@@ -612,6 +619,7 @@ class BaseChatClient(SerializationMixin, ABC):
messages: The message or messages to send to the model.
Keyword Args:
allow_multiple_tool_calls: Whether to allow multiple tool calls in a single response.
frequency_penalty: The frequency penalty to use.
logit_bias: The logit bias to use.
max_tokens: The maximum number of tokens to generate.
@@ -640,6 +648,7 @@ class BaseChatClient(SerializationMixin, ABC):
chat_options = _merge_chat_options(
base_chat_options=kwargs.pop("chat_options", None),
model_id=model_id,
allow_multiple_tool_calls=allow_multiple_tool_calls,
frequency_penalty=frequency_penalty,
logit_bias=logit_bias,
max_tokens=max_tokens,
@@ -0,0 +1,23 @@
# Copyright (c) Microsoft. All rights reserved.
import importlib
from typing import Any
IMPORT_PATH = "agent_framework_declarative"
PACKAGE_NAME = "agent-framework-declarative"
_IMPORTS = ["__version__", "AgentFactory", "DeclarativeLoaderError", "ProviderLookupError", "ProviderTypeMapping"]
def __getattr__(name: str) -> Any:
if name in _IMPORTS:
try:
return getattr(importlib.import_module(IMPORT_PATH), name)
except ModuleNotFoundError as exc:
raise ModuleNotFoundError(
f"The '{PACKAGE_NAME}' package is not installed, please do `pip install {PACKAGE_NAME}`"
) from exc
raise AttributeError(f"Module {IMPORT_PATH} has no attribute {name}.")
def __dir__() -> list[str]:
return _IMPORTS
@@ -0,0 +1,17 @@
# Copyright (c) Microsoft. All rights reserved.
from agent_framework_declarative import (
AgentFactory,
DeclarativeLoaderError,
ProviderLookupError,
ProviderTypeMapping,
__version__,
)
__all__ = [
"AgentFactory",
"DeclarativeLoaderError",
"ProviderLookupError",
"ProviderTypeMapping",
"__version__",
]
+1
View File
@@ -48,6 +48,7 @@ all = [
"agent-framework-azurefunctions",
"agent-framework-chatkit",
"agent-framework-copilotstudio",
"agent-framework-declarative",
"agent-framework-devui",
"agent-framework-lab",
"agent-framework-mem0",