| ## Agents | 
 |  | 
 | An `Agent` is a singleton-per-session component which runs outside of | 
 | the scope of a Story without any graphical UI. | 
 |  | 
 | Agents can schedule tasks (i.e. they can register to be woken up by the | 
 | framework to perform work), and provide services to other modular components. | 
 |  | 
 | Any modular component can connect to an agent and access its services (including | 
 | modules, shells, and other agents). | 
 |  | 
 | ### Environment | 
 |  | 
 | An agent is given access to two services provided by the modular framework in | 
 | its incoming namespace: | 
 |  | 
 | *   `fuchsia.modular.ComponentContext` which gives the agent access to | 
 |     functionality which is shared across components run under the modular | 
 |     framework (e.g. modules, shells, agents). | 
 | *   `fuchsia.modular.AgentContext` which gives agents access to agent specific | 
 |     functionality, like creating entity references and scheduling tasks. | 
 |  | 
 | An agent is expected to provide two services to the modular framework in its | 
 | outgoing namespace: | 
 |  | 
 | *   `fuchsia.modular.Agent` which allows the framework to forward connection | 
 |     requests from other components and tell the agent to run tasks. | 
 | *   `fuchsia.modular.Lifecycle` which allows the framework to signal the agent | 
 |     to terminate gracefully. | 
 |  | 
 | The aforementioned services enable communication between agents and the modular | 
 | framework, but agents can also expose custom FIDL services to components. For a | 
 | more detailed explanation of the mechanism which enables this service exchange | 
 | see Communication Mechanisms below. | 
 |  | 
 | ### Lifecycle | 
 |  | 
 | For most agents, when a component connects to an agent the framework will give | 
 | the component an `AgentController`. When the connecting component drops the | 
 | `AgentController` connection, and there are no outstanding connections, the | 
 | agent will be killed by the framework. | 
 |  | 
 | There are some agents for which the `sessionmgr` maintains an `AgentController`, | 
 | and thus the agent remains alive for the duration of the session. These | 
 | "session" agents also get access to `fuchsia.modular.PuppetMaster` in their | 
 | incoming namespace. | 
 |  | 
 | ### Communication mechanisms | 
 |  | 
 | Components can communicate with agents in two different ways: either by | 
 | connecting to a FIDL service exposed by the agent, or over a `MessageQueue`. | 
 |  | 
 | Which communication method is appropriate depends on the semantics of the | 
 | messages being passed. FIDL requires both agent and client to be running, | 
 | whereas message queues allow the life cycles of the sender and receiver to be | 
 | different. | 
 |  | 
 | #### FIDL Services | 
 |  | 
 | The modular framework will forward a `fuchsia.sys.ServiceProvider` request via | 
 | `fuchsia::modular::Agent.Connect` call, and will also provide the agent with an | 
 | identifier for the client which is requesting the service provider. | 
 |  | 
 | Any services added to the service provider will be exposed directly to the | 
 | connecting component. | 
 |  | 
 | To illustrate this, consider a module connecting to an agent: | 
 |  | 
 | The module calls `ConnectToAgent` on its `ComponentContext`, which contains a | 
 | `ServiceProvider` request as well as an `AgentController` request. | 
 |  | 
 | The agent controller request is used by the framework to keep the agent alive | 
 | until the agent controller is closed by the client. If more than one client is | 
 | connected to the same agent, the agent will be kept alive until all agent | 
 | controllers have been closed. | 
 |  | 
 | The service provider request is forwarded to the agent, along with a string | 
 | which identifies the client connecting to the agent. | 
 |  | 
 | #### Message Queues | 
 |  | 
 | Messages sent over message queues are untyped, but allow the life cycles of the | 
 | reader and writer to be decoupled. For example, an agent may provide a module | 
 | with a message queue which it can use to send messages to the agent. The agent | 
 | can then register to be woken up when a message is delivered on the queue. |