Skip to content

Commit 16ddade

Browse files
authored
Merge pull request #669 from MicrosoftDocs/main
9/26 Publish
2 parents 569780e + 1624893 commit 16ddade

5 files changed

Lines changed: 90 additions & 6 deletions

File tree

agent-framework/docfx.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
"zone_pivot_group_filename:": "zone_pivot_group.json",
4646
"uhfHeaderId": "MSDocsHeader-AgentFramework",
4747
"layout": "Conceptual",
48-
"breadcrumb_path": "/breadcrumb/agent-framework/toc.yml",
48+
"breadcrumb_path": "/agent-framework/breadcrumb/agent-framework/toc.json",
4949
"feedback_system": "Standard",
5050
"permissioned-type": "public"
5151
},

agent-framework/user-guide/workflows/core-concepts/events.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ RequestInfoEvent // A request is issued
4747
```python
4848
# Workflow lifecycle events
4949
WorkflowStartedEvent # Workflow execution begins
50-
WorkflowCompletedEvent # Workflow reaches completion
50+
WorkflowOutputEvent # Workflow produces an output
5151
WorkflowErrorEvent # Workflow encounters an error
5252

5353
# Executor events
@@ -98,7 +98,7 @@ await foreach (WorkflowEvent evt in run.WatchStreamAsync())
9898
from agent_framework import (
9999
ExecutorCompleteEvent,
100100
ExecutorInvokeEvent,
101-
WorkflowCompletedEvent,
101+
WorkflowOutputEvent,
102102
WorkflowErrorEvent,
103103
)
104104

@@ -108,8 +108,8 @@ async for event in workflow.run_stream(input_message):
108108
print(f"Starting {invoke.executor_id}")
109109
case ExecutorCompleteEvent() as complete:
110110
print(f"Completed {complete.executor_id}: {complete.data}")
111-
case WorkflowCompletedEvent() as finished:
112-
print(f"Workflow finished: {finished.data}")
111+
case WorkflowOutputEvent() as output:
112+
print(f"Workflow produced output: {output.data}")
113113
return
114114
case WorkflowErrorEvent() as error:
115115
print(f"Workflow error: {error.exception}")

agent-framework/user-guide/workflows/core-concepts/executors.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,46 @@ class SampleExecutor(Executor):
147147
await ctx.send_message(number * 2)
148148
```
149149

150+
### The `WorkflowContext` Object
151+
152+
The `WorkflowContext` object provides methods for the handler to interact with the workflow during execution. The `WorkflowContext` is parameterized with the type of messages the handler will emit and the type of outputs it can yield.
153+
154+
The most commonly used method is `send_message`, which allows the handler to send messages to connected executors.
155+
156+
```python
157+
from agent_framework import WorkflowContext
158+
159+
class SomeHandler(Executor):
160+
161+
@handler
162+
async def some_handler(message: str, ctx: WorkflowContext[str]) -> None:
163+
await ctx.send_message("Hello, World!")
164+
```
165+
166+
A handler can use `yield_output` to produce outputs that will be considered as workflow outputs and be returned/streamed to the caller as an output event:
167+
168+
```python
169+
from agent_framework import WorkflowContext
170+
171+
class SomeHandler(Executor):
172+
173+
@handler
174+
async def some_handler(message: str, ctx: WorkflowContext[Never, str]) -> None:
175+
await ctx.yield_output("Hello, World!")
176+
```
177+
178+
If a handler neither sends messages nor yields outputs, no type parameter is needed for `WorkflowContext`:
179+
180+
```python
181+
from agent_framework import WorkflowContext
182+
183+
class SomeHandler(Executor):
184+
185+
@handler
186+
async def some_handler(message: str, ctx: WorkflowContext) -> None:
187+
print("Doing some work...")
188+
```
189+
150190
::: zone-end
151191

152192
## Next Step

agent-framework/user-guide/workflows/observability.md

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ ms.service: semantic-kernel
1111

1212
# Microsoft Agent Framework Workflows - Observability
1313

14+
Observability provides insights into the internal state and behavior of workflows during execution. This includes logging, metrics, and tracing capabilities that help monitor and debug workflows.
15+
16+
Aside from the standard [GenAI telemetry](https://opentelemetry.io/docs/specs/semconv/gen-ai/), Agent Framework Workflows emits additional spans, logs, and metrics to provide deeper insights into workflow execution. These observability features help developers understand the flow of messages, the performance of executors, and any errors that may occur.
17+
1418
::: zone pivot="programming-language-csharp"
1519

1620
Coming soon...
@@ -19,6 +23,46 @@ Coming soon...
1923

2024
::: zone pivot="programming-language-python"
2125

22-
Coming soon...
26+
## Enable Observability
27+
28+
Observability is enabled framework-wide by setting the `ENABLE_OTEL=true` environment variable or calling `setup_observability()` at the beginning of your application.
29+
30+
```env
31+
# This is not required if you run `setup_observability()` in your code
32+
ENABLE_OTEL=true
33+
# Sensitive data (e.g., message content) will be included in logs and traces if this is set to true
34+
ENABLE_SENSITIVE_DATA=true
35+
```
36+
37+
```python
38+
from agent_framework.observability import setup_observability
39+
40+
setup_observability(enable_sensitive_data=True)
41+
```
42+
43+
## Workflow Spans
44+
45+
| Span Name | Description |
46+
|----------------------------------|--------------------------------------------------|
47+
| `workflow.build` | For each workflow build |
48+
| `workflow.run` | For each workflow execution |
49+
| `message.send` | For each message sent to an executor |
50+
| `executor.process` | For each executor processing a message |
51+
| `edge_group.process` | For each edge group processing a message |
52+
53+
### Links between Spans
54+
55+
When an executor sends a message to another executor, the `message.send` span is created as a child of the `executor.process` span. However, the `executor.process` span of the target executor will not be a child of the `message.send` span because the execution is not nested. Instead, the `executor.process` span of the target executor is linked to the `message.send` span of the source executor. This creates a traceable path through the workflow execution.
56+
57+
For example:
58+
59+
![Span Relationships](./resources/images/workflow-trace.png)
2360

2461
::: zone-end
62+
63+
## Next Steps
64+
65+
- [Learn how to use agents in workflows](./using-agents.md) to build intelligent workflows.
66+
- [Learn how to handle requests and responses](./request-and-response.md) in workflows.
67+
- [Learn how to manage state](./shared-states.md) in workflows.
68+
- [Learn how to create checkpoints and resume from them](./checkpoints.md).
27.6 KB
Loading

0 commit comments

Comments
 (0)