Agent / Expose, do not reimplement

The mental model

There are four different values in normal agent code. Keeping them separate makes the API much easier to read:

Foldkit application
        App
         |
         | Agent.forApplication(App)
         v
application-specialized builder
     AgentBuilder
         |
         | .make(...)
         v
protocol-neutral contract
    AssistantAgent
         |
         | .bind({ host })
         v
live AgentRuntime
         |
         +--> WebMCP
         +--> MCP
         +--> A2A
         +--> Agent Native

A useful naming rule is builder first, contract second:

ts
const AgentBuilder = Agent.forApplication(App).withPrincipal<Principal>()

const AssistantAgent = AgentBuilder.make({
  // ...the actual agent contract
})

AgentBuilder is not an agent. It is a typed DSL specialized to this application's Model, Message union, and Principal type. Its helpers such as make, expose, and bind now know those types.

AssistantAgent is the actual contract: what this agent may see, what it may do, which policies apply, how completion is recognized, and which read-only resources it exposes. This is the value adapters describe and serve.

Binding that contract to a running application produces the live runtime that can read the current Model and dispatch Messages.