Update references in docs (#4590)

* Update agent doc

* Remove outdated doc

* Update references

* Update readme

* Update readme
This commit is contained in:
Eric Zhu
2024-12-06 01:59:28 -08:00
committed by GitHub
parent fa550c2c36
commit 8dac072658
33 changed files with 1875 additions and 1971 deletions

View File

@@ -188,8 +188,10 @@
"The following preset agents are available:\n",
"\n",
"- {py:class}`~autogen_agentchat.agents.CodeExecutorAgent`: An agent that can execute code.\n",
"- {py:class}`~autogen_ext.agents.OpenAIAssistantAgent`: An agent that is backed by an OpenAI Assistant, with ability to use custom tools.\n",
"- {py:class}`~autogen_ext.agents.MultimodalWebSurfer`: A multi-modal agent that can search the web and visit web pages for information."
"- {py:class}`~autogen_ext.agents.openai.OpenAIAssistantAgent`: An agent that is backed by an OpenAI Assistant, with ability to use custom tools.\n",
"- {py:class}`~autogen_ext.agents.web_surfer.MultimodalWebSurfer`: A multi-modal agent that can search the web and visit web pages for information.\n",
"- {py:class}`~autogen_ext.agents.file_surfer.FileSurfer`: An agent that can search and browse local files for information.\n",
"- {py:class}`~autogen_ext.agents.video_surfer.VideoSurfer`: An agent that can watch videos for information."
]
},
{
@@ -248,7 +250,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.6"
"version": "3.11.5"
}
},
"nbformat": 4,

View File

@@ -8,42 +8,23 @@
"\n",
"The model clients included in AutoGen emit structured events that can be used to track the usage of the model. This notebook demonstrates how to use the logger to track the usage of the model.\n",
"\n",
"These events are logged to the logger with the name: :py:attr:`autogen_core.application.logging.EVENT_LOGGER_NAME`."
"These events are logged to the logger with the name: :py:attr:`autogen_core.EVENT_LOGGER_NAME`."
]
},
{
"cell_type": "code",
"execution_count": 1,
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import logging\n",
"\n",
"from autogen_core.application.logging.events import LLMCallEvent\n",
"from autogen_core.logging import LLMCallEvent\n",
"\n",
"\n",
"class LLMUsageTracker(logging.Handler):\n",
" def __init__(self) -> None:\n",
" \"\"\"Logging handler that tracks the number of tokens used in the prompt and completion.\n",
"\n",
" Example:\n",
"\n",
" .. code-block:: python\n",
"\n",
" from autogen_core.application.logging import LLMUsageTracker, EVENT_LOGGER_NAME\n",
"\n",
" # Set up the logging configuration to use the custom handler\n",
" logger = logging.getLogger(EVENT_LOGGER_NAME)\n",
" logger.setLevel(logging.INFO)\n",
" llm_usage = LLMUsageTracker()\n",
" logger.handlers = [llm_usage]\n",
"\n",
" # ...\n",
"\n",
" print(llm_usage.prompt_tokens)\n",
" print(llm_usage.completion_tokens)\n",
"\n",
" \"\"\"\n",
" \"\"\"Logging handler that tracks the number of tokens used in the prompt and completion.\"\"\"\n",
" super().__init__()\n",
" self._prompt_tokens = 0\n",
" self._completion_tokens = 0\n",
@@ -89,7 +70,7 @@
"metadata": {},
"outputs": [],
"source": [
"from autogen_core.application.logging import EVENT_LOGGER_NAME\n",
"from autogen_core import EVENT_LOGGER_NAME\n",
"\n",
"# Set up the logging configuration to use the custom handler\n",
"logger = logging.getLogger(EVENT_LOGGER_NAME)\n",
@@ -120,7 +101,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.5"
"version": "3.11.5"
}
},
"nbformat": 4,

View File

@@ -1,179 +1,179 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Termination using Intervention Handler\n",
"\n",
"```{note}\n",
"This method is valid when using {py:class}`~autogen_core.application.SingleThreadedAgentRuntime`.\n",
"```\n",
"\n",
"There are many different ways to handle termination in `autogen_core`. Ultimately, the goal is to detect that the runtime no longer needs to be executed and you can proceed to finalization tasks. One way to do this is to use an {py:class}`autogen_core.base.intervention.InterventionHandler` to detect a termination message and then act on it."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"from dataclasses import dataclass\n",
"from typing import Any\n",
"\n",
"from autogen_core import (\n",
" AgentId,\n",
" DefaultTopicId,\n",
" MessageContext,\n",
" RoutedAgent,\n",
" SingleThreadedAgentRuntime,\n",
" default_subscription,\n",
" message_handler,\n",
")\n",
"from autogen_core.base.intervention import DefaultInterventionHandler"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First, we define a dataclass for regular message and message that will be used to signal termination."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"@dataclass\n",
"class Message:\n",
" content: Any\n",
"\n",
"\n",
"@dataclass\n",
"class Termination:\n",
" reason: str"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We code our agent to publish a termination message when it decides it is time to terminate."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"@default_subscription\n",
"class AnAgent(RoutedAgent):\n",
" def __init__(self) -> None:\n",
" super().__init__(\"MyAgent\")\n",
" self.received = 0\n",
"\n",
" @message_handler\n",
" async def on_new_message(self, message: Message, ctx: MessageContext) -> None:\n",
" self.received += 1\n",
" if self.received > 3:\n",
" await self.publish_message(Termination(reason=\"Reached maximum number of messages\"), DefaultTopicId())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Next, we create an InterventionHandler that will detect the termination message and act on it. This one hooks into publishes and when it encounters `Termination` it alters its internal state to indicate that termination has been requested."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"class TerminationHandler(DefaultInterventionHandler):\n",
" def __init__(self) -> None:\n",
" self._termination_value: Termination | None = None\n",
"\n",
" async def on_publish(self, message: Any, *, sender: AgentId | None) -> Any:\n",
" if isinstance(message, Termination):\n",
" self._termination_value = message\n",
" return message\n",
"\n",
" @property\n",
" def termination_value(self) -> Termination | None:\n",
" return self._termination_value\n",
"\n",
" @property\n",
" def has_terminated(self) -> bool:\n",
" return self._termination_value is not None"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, we add this handler to the runtime and use it to detect termination and stop the runtime when the termination message is received."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Termination(reason='Reached maximum number of messages')\n"
]
}
],
"source": [
"termination_handler = TerminationHandler()\n",
"runtime = SingleThreadedAgentRuntime(intervention_handlers=[termination_handler])\n",
"\n",
"await AnAgent.register(runtime, \"my_agent\", AnAgent)\n",
"\n",
"runtime.start()\n",
"\n",
"# Publish more than 3 messages to trigger termination.\n",
"await runtime.publish_message(Message(\"hello\"), DefaultTopicId())\n",
"await runtime.publish_message(Message(\"hello\"), DefaultTopicId())\n",
"await runtime.publish_message(Message(\"hello\"), DefaultTopicId())\n",
"await runtime.publish_message(Message(\"hello\"), DefaultTopicId())\n",
"\n",
"# Wait for termination.\n",
"await runtime.stop_when(lambda: termination_handler.has_terminated)\n",
"\n",
"print(termination_handler.termination_value)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.9"
}
},
"nbformat": 4,
"nbformat_minor": 2
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Termination using Intervention Handler\n",
"\n",
"```{note}\n",
"This method is valid when using {py:class}`~autogen_core.SingleThreadedAgentRuntime`.\n",
"```\n",
"\n",
"There are many different ways to handle termination in `autogen_core`. Ultimately, the goal is to detect that the runtime no longer needs to be executed and you can proceed to finalization tasks. One way to do this is to use an {py:class}`autogen_core.base.intervention.InterventionHandler` to detect a termination message and then act on it."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"from dataclasses import dataclass\n",
"from typing import Any\n",
"\n",
"from autogen_core import (\n",
" AgentId,\n",
" DefaultTopicId,\n",
" MessageContext,\n",
" RoutedAgent,\n",
" SingleThreadedAgentRuntime,\n",
" default_subscription,\n",
" message_handler,\n",
")\n",
"from autogen_core.base.intervention import DefaultInterventionHandler"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First, we define a dataclass for regular message and message that will be used to signal termination."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"@dataclass\n",
"class Message:\n",
" content: Any\n",
"\n",
"\n",
"@dataclass\n",
"class Termination:\n",
" reason: str"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We code our agent to publish a termination message when it decides it is time to terminate."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"@default_subscription\n",
"class AnAgent(RoutedAgent):\n",
" def __init__(self) -> None:\n",
" super().__init__(\"MyAgent\")\n",
" self.received = 0\n",
"\n",
" @message_handler\n",
" async def on_new_message(self, message: Message, ctx: MessageContext) -> None:\n",
" self.received += 1\n",
" if self.received > 3:\n",
" await self.publish_message(Termination(reason=\"Reached maximum number of messages\"), DefaultTopicId())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Next, we create an InterventionHandler that will detect the termination message and act on it. This one hooks into publishes and when it encounters `Termination` it alters its internal state to indicate that termination has been requested."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"class TerminationHandler(DefaultInterventionHandler):\n",
" def __init__(self) -> None:\n",
" self._termination_value: Termination | None = None\n",
"\n",
" async def on_publish(self, message: Any, *, sender: AgentId | None) -> Any:\n",
" if isinstance(message, Termination):\n",
" self._termination_value = message\n",
" return message\n",
"\n",
" @property\n",
" def termination_value(self) -> Termination | None:\n",
" return self._termination_value\n",
"\n",
" @property\n",
" def has_terminated(self) -> bool:\n",
" return self._termination_value is not None"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Finally, we add this handler to the runtime and use it to detect termination and stop the runtime when the termination message is received."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Termination(reason='Reached maximum number of messages')\n"
]
}
],
"source": [
"termination_handler = TerminationHandler()\n",
"runtime = SingleThreadedAgentRuntime(intervention_handlers=[termination_handler])\n",
"\n",
"await AnAgent.register(runtime, \"my_agent\", AnAgent)\n",
"\n",
"runtime.start()\n",
"\n",
"# Publish more than 3 messages to trigger termination.\n",
"await runtime.publish_message(Message(\"hello\"), DefaultTopicId())\n",
"await runtime.publish_message(Message(\"hello\"), DefaultTopicId())\n",
"await runtime.publish_message(Message(\"hello\"), DefaultTopicId())\n",
"await runtime.publish_message(Message(\"hello\"), DefaultTopicId())\n",
"\n",
"# Wait for termination.\n",
"await runtime.stop_when(lambda: termination_handler.has_terminated)\n",
"\n",
"print(termination_handler.termination_value)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.9"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

View File

@@ -1,28 +0,0 @@
# API Layers
The API consists of the following layers:
- {py:mod}`autogen_core.base`
- {py:mod}`autogen_core.application`
- {py:mod}`autogen_core.components`
The following diagram shows the relationship between the layers.
![Layers](layers.svg)
The {py:mod}`autogen_core.base` layer defines the
core interfaces and base classes for agents, messages, and runtime.
This layer is the foundation of the framework and is used by the other layers.
The {py:mod}`autogen_core.application` layer provides concrete implementations of
runtime and utilities like logging for building multi-agent applications.
The {py:mod}`autogen_core.components` layer provides reusable components for building
AI agents, including type-routed agents, AI model clients, tools for AI models,
code execution sandboxes, and memory stores.
The layers are loosely coupled and can be used independently. For example,
you can swap out the runtime in the {py:mod}`autogen_core.application` layer with your own
runtime implementation.
You can also skip the components in the {py:mod}`autogen_core.components` layer and
build your own components.

View File

@@ -4,7 +4,7 @@ At the foundation level, the framework provides a _runtime environment_, which f
communication between agents, manages their identities and lifecycles,
and enforce security and privacy boundaries.
It supports two types of runtime environment: *standalone* and *distributed*.
It supports two types of runtime environment: _standalone_ and _distributed_.
Both types provide a common set of APIs for building multi-agent applications,
so you can switch between them without changing your agent implementation.
Each type can also have multiple implementations.
@@ -13,7 +13,7 @@ Each type can also have multiple implementations.
Standalone runtime is suitable for single-process applications where all agents
are implemented in the same programming language and running in the same process.
In the Python API, an example of standalone runtime is the {py:class}`~autogen_core.application.SingleThreadedAgentRuntime`.
In the Python API, an example of standalone runtime is the {py:class}`~autogen_core.SingleThreadedAgentRuntime`.
The following diagram shows the standalone runtime in the framework.
@@ -44,4 +44,3 @@ They advertise to the host servicer the agents they run and manage the agents' l
Agents work the same way as in the standalone runtime so that developers can
switch between the two runtime types with no change to their agent implementation.

View File

@@ -8,7 +8,6 @@ and the system architecture.
agent-and-multi-agent-application
architecture
api-layers
application-stack
agent-identity-and-lifecycle
topic-and-subscription

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 100 KiB

View File

@@ -26,7 +26,7 @@
"an agent runtime provides the necessary infrastructure to facilitate communication\n",
"between agents, manage agent lifecycles, enforce security boundaries, and support monitoring and\n",
"debugging.\n",
"For local development, developers can use {py:class}`~autogen_core.application.SingleThreadedAgentRuntime`,\n",
"For local development, developers can use {py:class}`~autogen_core.SingleThreadedAgentRuntime`,\n",
"which can be embedded in a Python application.\n",
"\n",
"```{note}\n",
@@ -111,7 +111,7 @@
"```\n",
"\n",
"To register an agent type with the \n",
"{py:class}`~autogen_core.application.SingleThreadedAgentRuntime`,\n",
"{py:class}`~autogen_core.SingleThreadedAgentRuntime`,\n",
"the following code can be used:"
]
},
@@ -187,7 +187,7 @@
"The above code snippet uses `runtime.start()` to start a background task\n",
"to process and deliver messages to recepients' message handlers.\n",
"This is a feature of the\n",
"local embedded runtime {py:class}`~autogen_core.application.SingleThreadedAgentRuntime`.\n",
"local embedded runtime {py:class}`~autogen_core.SingleThreadedAgentRuntime`.\n",
"\n",
"To stop the background task immediately, use the `stop()` method:"
]

View File

@@ -94,7 +94,7 @@
"metadata": {},
"source": [
"Now we can set up the worker agent runtimes.\n",
"We use {py:class}`~autogen_core.application.GrpcWorkerAgentRuntime`.\n",
"We use {py:class}`~autogen_ext.runtimes.grpc.GrpcWorkerAgentRuntime`.\n",
"We set up two worker runtimes. Each runtime hosts one agent.\n",
"All agents publish and subscribe to the default topic, so they can see all\n",
"messages being published.\n",

View File

@@ -5,11 +5,11 @@ AutoGen uses Python's built-in [`logging`](https://docs.python.org/3/library/log
There are two kinds of logging:
- **Trace logging**: This is used for debugging and is human readable messages to indicate what is going on. This is intended for a developer to understand what is happening in the code. The content and format of these logs should not be depended on by other systems.
- Name: {py:attr}`~autogen_core.application.logging.TRACE_LOGGER_NAME`.
- Name: {py:attr}`~autogen_core.TRACE_LOGGER_NAME`.
- **Structured logging**: This logger emits structured events that can be consumed by other systems. The content and format of these logs can be depended on by other systems.
- Name: {py:attr}`~autogen_core.application.logging.EVENT_LOGGER_NAME`.
- See the module {py:mod}`autogen_core.application.logging.events` to see the available events.
- {py:attr}`~autogen_core.application.logging.ROOT_LOGGER` can be used to enable or disable all logs.
- Name: {py:attr}`~autogen_core.EVENT_LOGGER_NAME`.
- See the module {py:mod}`autogen_core.logging` to see the available events.
- {py:attr}`~autogen_core.ROOT_LOGGER_NAME` can be used to enable or disable all logs.
## Enabling logging output
@@ -18,7 +18,7 @@ To enable trace logging, you can use the following code:
```python
import logging
from autogen_core.application.logging import TRACE_LOGGER_NAME
from autogen_core import TRACE_LOGGER_NAME
logging.basicConfig(level=logging.WARNING)
logger = logging.getLogger(TRACE_LOGGER_NAME)
@@ -62,7 +62,6 @@ my_handler = MyHandler()
logger.handlers = [my_handler]
```
## Emitting logs
These two names are the root loggers for these types. Code that emits logs should use a child logger of these loggers. For example, if you are writing a module `my_module` and you want to emit trace logs, you should use the logger named:
@@ -70,7 +69,7 @@ These two names are the root loggers for these types. Code that emits logs shoul
```python
import logging
from autogen_core.application.logging import TRACE_LOGGER_NAME
from autogen_core import TRACE_LOGGER_NAME
logger = logging.getLogger(f"{TRACE_LOGGER_NAME}.my_module")
```
@@ -90,7 +89,7 @@ class MyEvent:
Then it could be emitted in code like this:
```python
from autogen_core.application.logging import EVENT_LOGGER_NAME
from autogen_core import EVENT_LOGGER_NAME
logger = logging.getLogger(EVENT_LOGGER_NAME + ".my_module")
logger.info(MyEvent("timestamp", "message"))

File diff suppressed because one or more lines are too long