agent-framework-core 1.1.1__tar.gz → 1.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/PKG-INFO +1 -1
  2. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/__init__.py +18 -0
  3. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_feature_stage.py +1 -0
  4. agent_framework_core-1.2.1/agent_framework/_telemetry.py +134 -0
  5. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/_events.py +7 -0
  6. agent_framework_core-1.2.1/agent_framework/_workflows/_functional.py +1551 -0
  7. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/_workflow.py +5 -5
  8. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/a2a/__init__.py +2 -1
  9. agent_framework_core-1.2.1/agent_framework/a2a/__init__.pyi +5 -0
  10. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/exceptions.py +2 -1
  11. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/foundry/__init__.py +1 -0
  12. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/github/__init__.py +2 -0
  13. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/github/__init__.pyi +2 -0
  14. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/pyproject.toml +1 -1
  15. agent_framework_core-1.1.1/agent_framework/_telemetry.py +0 -97
  16. agent_framework_core-1.1.1/agent_framework/a2a/__init__.pyi +0 -9
  17. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/LICENSE +0 -0
  18. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/README.md +0 -0
  19. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_agents.py +0 -0
  20. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_clients.py +0 -0
  21. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_compaction.py +0 -0
  22. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_docstrings.py +0 -0
  23. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_evaluation.py +0 -0
  24. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_mcp.py +0 -0
  25. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_middleware.py +0 -0
  26. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_serialization.py +0 -0
  27. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_sessions.py +0 -0
  28. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_settings.py +0 -0
  29. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_skills.py +0 -0
  30. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_tools.py +0 -0
  31. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_types.py +0 -0
  32. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/__init__.py +0 -0
  33. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/_agent.py +0 -0
  34. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/_agent_executor.py +0 -0
  35. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/_agent_utils.py +0 -0
  36. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/_checkpoint.py +0 -0
  37. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/_checkpoint_encoding.py +0 -0
  38. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/_const.py +0 -0
  39. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/_conversation_history.py +0 -0
  40. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/_edge.py +0 -0
  41. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/_edge_runner.py +0 -0
  42. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/_executor.py +0 -0
  43. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/_function_executor.py +0 -0
  44. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/_message_utils.py +0 -0
  45. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/_model_utils.py +0 -0
  46. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/_request_info_mixin.py +0 -0
  47. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/_runner.py +0 -0
  48. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/_runner_context.py +0 -0
  49. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/_state.py +0 -0
  50. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/_typing_utils.py +0 -0
  51. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/_validation.py +0 -0
  52. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/_viz.py +0 -0
  53. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/_workflow_builder.py +0 -0
  54. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/_workflow_context.py +0 -0
  55. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/_workflows/_workflow_executor.py +0 -0
  56. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/ag_ui/__init__.py +0 -0
  57. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/ag_ui/__init__.pyi +0 -0
  58. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/amazon/__init__.py +0 -0
  59. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/amazon/__init__.pyi +0 -0
  60. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/anthropic/__init__.py +0 -0
  61. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/anthropic/__init__.pyi +0 -0
  62. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/azure/__init__.py +0 -0
  63. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/azure/__init__.pyi +0 -0
  64. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/chatkit/__init__.py +0 -0
  65. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/chatkit/__init__.pyi +0 -0
  66. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/declarative/__init__.py +0 -0
  67. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/declarative/__init__.pyi +0 -0
  68. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/devui/__init__.py +0 -0
  69. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/devui/__init__.pyi +0 -0
  70. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/foundry/__init__.pyi +0 -0
  71. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/google/__init__.py +0 -0
  72. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/google/__init__.pyi +0 -0
  73. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/lab/__init__.py +0 -0
  74. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/mem0/__init__.py +0 -0
  75. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/mem0/__init__.pyi +0 -0
  76. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/microsoft/__init__.py +0 -0
  77. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/microsoft/__init__.pyi +0 -0
  78. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/observability.py +0 -0
  79. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/ollama/__init__.py +0 -0
  80. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/ollama/__init__.pyi +0 -0
  81. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/openai/__init__.py +0 -0
  82. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/openai/__init__.pyi +0 -0
  83. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/orchestrations/__init__.py +0 -0
  84. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/orchestrations/__init__.pyi +0 -0
  85. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/py.typed +0 -0
  86. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/redis/__init__.py +0 -0
  87. {agent_framework_core-1.1.1 → agent_framework_core-1.2.1}/agent_framework/redis/__init__.pyi +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agent-framework-core
3
- Version: 1.1.1
3
+ Version: 1.2.1
4
4
  Summary: Microsoft Agent Framework for building AI Agents with Python. This is the core package that has all the core abstractions and implementations.
5
5
  Author-email: Microsoft <af-support@microsoft.com>
6
6
  Requires-Python: >=3.10
@@ -213,6 +213,15 @@ from ._workflows._executor import (
213
213
  handler,
214
214
  )
215
215
  from ._workflows._function_executor import FunctionExecutor, executor
216
+ from ._workflows._functional import (
217
+ FunctionalWorkflow,
218
+ FunctionalWorkflowAgent,
219
+ RunContext,
220
+ StepWrapper,
221
+ get_run_context,
222
+ step,
223
+ workflow,
224
+ )
216
225
  from ._workflows._request_info_mixin import response_handler
217
226
  from ._workflows._runner import Runner
218
227
  from ._workflows._runner_context import (
@@ -238,6 +247,7 @@ from ._workflows._workflow_executor import (
238
247
  WorkflowExecutor,
239
248
  )
240
249
  from .exceptions import (
250
+ AgentFrameworkException,
241
251
  MiddlewareException,
242
252
  UserInputRequiredException,
243
253
  WorkflowCheckpointException,
@@ -271,6 +281,7 @@ __all__ = [
271
281
  "AgentExecutor",
272
282
  "AgentExecutorRequest",
273
283
  "AgentExecutorResponse",
284
+ "AgentFrameworkException",
274
285
  "AgentMiddleware",
275
286
  "AgentMiddlewareLayer",
276
287
  "AgentMiddlewareTypes",
@@ -332,6 +343,8 @@ __all__ = [
332
343
  "FunctionMiddleware",
333
344
  "FunctionMiddlewareTypes",
334
345
  "FunctionTool",
346
+ "FunctionalWorkflow",
347
+ "FunctionalWorkflowAgent",
335
348
  "GeneratedEmbeddings",
336
349
  "GraphConnectivityError",
337
350
  "HistoryProvider",
@@ -354,6 +367,7 @@ __all__ = [
354
367
  "ResponseStream",
355
368
  "Role",
356
369
  "RoleLiteral",
370
+ "RunContext",
357
371
  "Runner",
358
372
  "RunnerContext",
359
373
  "SecretString",
@@ -366,6 +380,7 @@ __all__ = [
366
380
  "SkillScriptRunner",
367
381
  "SkillsProvider",
368
382
  "SlidingWindowStrategy",
383
+ "StepWrapper",
369
384
  "SubWorkflowRequestMessage",
370
385
  "SubWorkflowResponseMessage",
371
386
  "SummarizationStrategy",
@@ -424,6 +439,7 @@ __all__ = [
424
439
  "evaluator",
425
440
  "executor",
426
441
  "function_middleware",
442
+ "get_run_context",
427
443
  "handler",
428
444
  "included_messages",
429
445
  "included_token_count",
@@ -439,6 +455,7 @@ __all__ = [
439
455
  "register_state_type",
440
456
  "resolve_agent_id",
441
457
  "response_handler",
458
+ "step",
442
459
  "tool",
443
460
  "tool_call_args_match",
444
461
  "tool_called_check",
@@ -447,4 +464,5 @@ __all__ = [
447
464
  "validate_tool_mode",
448
465
  "validate_tools",
449
466
  "validate_workflow_graph",
467
+ "workflow",
450
468
  ]
@@ -48,6 +48,7 @@ class ExperimentalFeature(str, Enum):
48
48
 
49
49
  EVALS = "EVALS"
50
50
  FILE_HISTORY = "FILE_HISTORY"
51
+ FUNCTIONAL_WORKFLOWS = "FUNCTIONAL_WORKFLOWS"
51
52
  SKILLS = "SKILLS"
52
53
  TOOLBOXES = "TOOLBOXES"
53
54
 
@@ -0,0 +1,134 @@
1
+ # Copyright (c) Microsoft. All rights reserved.
2
+
3
+ from __future__ import annotations
4
+
5
+ import contextlib
6
+ import logging
7
+ import os
8
+ from typing import Any, Final
9
+
10
+ from . import __version__ as version_info
11
+
12
+ logger = logging.getLogger("agent_framework")
13
+
14
+
15
+ # Note that if this environment variable does not exist, user agent telemetry is enabled.
16
+ USER_AGENT_TELEMETRY_DISABLED_ENV_VAR = "AGENT_FRAMEWORK_USER_AGENT_DISABLED"
17
+ IS_TELEMETRY_ENABLED = os.environ.get(USER_AGENT_TELEMETRY_DISABLED_ENV_VAR, "false").lower() not in ["true", "1"]
18
+
19
+ APP_INFO = (
20
+ {
21
+ "agent-framework-version": f"python/{version_info}", # type: ignore[has-type]
22
+ }
23
+ if IS_TELEMETRY_ENABLED
24
+ else None
25
+ )
26
+ USER_AGENT_KEY: Final[str] = "User-Agent"
27
+ HTTP_USER_AGENT: Final[str] = "agent-framework-python"
28
+ AGENT_FRAMEWORK_USER_AGENT = f"{HTTP_USER_AGENT}/{version_info}" # type: ignore[has-type]
29
+
30
+ # This environment variable is reserved by the Foundry hosting environment to
31
+ # indicate that the agent is running in a hosted environment.
32
+ _FOUNDRY_HOSTING_ENV_VAR = "FOUNDRY_HOSTING_ENVIRONMENT"
33
+ # This prefix is added to the user agent string when the agent is running in a hosted environment.
34
+ _HOSTED_USER_AGENT_PREFIX = "foundry-hosting"
35
+
36
+ _user_agent_prefixes: set[str] = set()
37
+ _hosted_env_detected: bool = False
38
+
39
+
40
+ def _add_user_agent_prefix(prefix: str) -> None:
41
+ """Permanently add a prefix to the user agent string.
42
+
43
+ This is used by hosting layers to identify themselves in telemetry.
44
+ Once added, the prefix applies to all subsequent user agent strings.
45
+
46
+ Args:
47
+ prefix: The prefix to add (e.g. "foundry-hosting").
48
+ """
49
+ if prefix:
50
+ _user_agent_prefixes.add(prefix)
51
+
52
+
53
+ def _detect_hosted_environment() -> None:
54
+ """Detect if running in a hosted environment and add the user agent prefix.
55
+
56
+ Checks the ``FOUNDRY_HOSTING_ENVIRONMENT`` env var first, then falls back
57
+ to checking whether the agent server SDK is installed (via
58
+ ``importlib.util.find_spec``) before importing it, to avoid unnecessary
59
+ import overhead for non-hosted scenarios.
60
+ """
61
+ global _hosted_env_detected
62
+ if _hosted_env_detected:
63
+ return
64
+
65
+ if (env_value := os.environ.get(_FOUNDRY_HOSTING_ENV_VAR)) is not None:
66
+ # Env var exists — trust its value and skip the fallback.
67
+ if env_value:
68
+ _add_user_agent_prefix(_HOSTED_USER_AGENT_PREFIX)
69
+ _hosted_env_detected = True
70
+ return
71
+
72
+ # Env var not set — fall back to AgentConfig as a second layer of defense.
73
+ # Use find_spec to avoid the cost of a full import when the SDK is not installed.
74
+ import importlib.util
75
+
76
+ try:
77
+ if importlib.util.find_spec("azure.ai.agentserver.core") is None:
78
+ return
79
+ except (ModuleNotFoundError, ValueError):
80
+ return
81
+ with contextlib.suppress(ImportError, AttributeError):
82
+ from azure.ai.agentserver.core import ( # pyright: ignore[reportMissingImports]
83
+ AgentConfig, # pyright: ignore[reportUnknownVariableType]
84
+ )
85
+
86
+ if AgentConfig.from_env().is_hosted: # pyright: ignore[reportUnknownMemberType]
87
+ _add_user_agent_prefix(_HOSTED_USER_AGENT_PREFIX)
88
+ _hosted_env_detected = True
89
+
90
+
91
+ def get_user_agent() -> str:
92
+ """Return the full user agent string including any registered prefixes."""
93
+ _detect_hosted_environment()
94
+ if not _user_agent_prefixes:
95
+ return AGENT_FRAMEWORK_USER_AGENT
96
+ return f"{'/'.join(sorted(_user_agent_prefixes))}/{AGENT_FRAMEWORK_USER_AGENT}"
97
+
98
+
99
+ def prepend_agent_framework_to_user_agent(headers: dict[str, Any] | None = None) -> dict[str, Any]:
100
+ """Prepend "agent-framework" to the User-Agent in the headers.
101
+
102
+ When user agent telemetry is disabled through the ``AGENT_FRAMEWORK_USER_AGENT_DISABLED``
103
+ environment variable, the User-Agent header will not include the agent-framework information.
104
+ It will be sent back as is, or as an empty dict when None is passed.
105
+
106
+ Args:
107
+ headers: The existing headers dictionary.
108
+
109
+ Returns:
110
+ A new dict with "User-Agent" set to "agent-framework-python/{version}" if headers is None.
111
+ The modified headers dictionary with "agent-framework-python/{version}" prepended to the User-Agent.
112
+
113
+ Examples:
114
+ .. code-block:: python
115
+
116
+ from agent_framework import prepend_agent_framework_to_user_agent
117
+
118
+ # Add agent-framework to new headers
119
+ headers = prepend_agent_framework_to_user_agent()
120
+ print(headers["User-Agent"]) # "agent-framework-python/0.1.0"
121
+
122
+ # Prepend to existing headers
123
+ existing = {"User-Agent": "my-app/1.0"}
124
+ headers = prepend_agent_framework_to_user_agent(existing)
125
+ print(headers["User-Agent"]) # "agent-framework-python/0.1.0 my-app/1.0"
126
+ """
127
+ if not IS_TELEMETRY_ENABLED:
128
+ return headers or {}
129
+ user_agent = get_user_agent()
130
+ if not headers:
131
+ return {USER_AGENT_KEY: user_agent}
132
+ headers[USER_AGENT_KEY] = f"{user_agent} {headers[USER_AGENT_KEY]}" if USER_AGENT_KEY in headers else user_agent
133
+
134
+ return headers
@@ -120,6 +120,7 @@ WorkflowEventType = Literal[
120
120
  "executor_invoked", # Executor handler was called (use .executor_id, .data)
121
121
  "executor_completed", # Executor handler completed (use .executor_id, .data)
122
122
  "executor_failed", # Executor handler raised error (use .executor_id, .details)
123
+ "executor_bypassed", # Executor skipped via cache hit during replay (use .executor_id, .data)
123
124
  # Orchestration event types (use .data for typed payload)
124
125
  "group_chat", # Group chat orchestrator events (use .data as GroupChatRequestSentEvent | GroupChatResponseReceivedEvent) # noqa: E501
125
126
  "handoff_sent", # Handoff routing events (use .data as HandoffSentEvent)
@@ -148,6 +149,7 @@ class WorkflowEvent(Generic[DataT]):
148
149
  - `WorkflowEvent.executor_invoked(executor_id)` - executor handler called
149
150
  - `WorkflowEvent.executor_completed(executor_id)` - executor handler completed
150
151
  - `WorkflowEvent.executor_failed(executor_id, details)` - executor handler failed
152
+ - `WorkflowEvent.executor_bypassed(executor_id)` - executor skipped via cache hit
151
153
 
152
154
  The generic parameter DataT represents the type of the event's data payload:
153
155
  - Lifecycle events: `WorkflowEvent[None]` (data is None)
@@ -318,6 +320,11 @@ class WorkflowEvent(Generic[DataT]):
318
320
  """Create an 'executor_failed' event when an executor handler raises an error."""
319
321
  return WorkflowEvent("executor_failed", executor_id=executor_id, data=details, details=details)
320
322
 
323
+ @classmethod
324
+ def executor_bypassed(cls, executor_id: str, data: DataT | None = None) -> WorkflowEvent[DataT]:
325
+ """Create an 'executor_bypassed' event when a step is skipped via cache hit during replay."""
326
+ return cls("executor_bypassed", executor_id=executor_id, data=data)
327
+
321
328
  # ==========================================================================
322
329
  # Property for type-safe access
323
330
  # ==========================================================================