showcase/shell-docs/src/content/docs/backend/self-managed-agents.mdx
The frontend provider usually talks to your agents through the
runtime: the frontend hits runtimeUrl, the runtime
discovers agents from /info, and a proxy forwards every run server-side. But you
can also hand the provider AG-UI agent instances directly and skip the runtime
for those agents. There are separate production and local-development options,
and choosing the right one matters.
selfManagedAgents is the supported configuration option for connecting agents you manage
yourself, for example an HttpAgent pointing at an
AG-UI-compatible backend you own and have already secured:
const supportAgent = new HttpAgent({ url: "https://agents.example.com/support", });
<CopilotKit selfManagedAgents={{ "support-agent": supportAgent }}
<YourApp /> </CopilotKit>; ``` </FrontendOnly> <FrontendOnly frontend="angular"> ```ts title="src/app/app.config.ts" import { ApplicationConfig } from "@angular/core"; import { HttpAgent } from "@ag-ui/client"; import { provideCopilotKit } from "@copilotkit/angular";
const supportAgent = new HttpAgent({ url: "https://agents.example.com/support", });
export const appConfig: ApplicationConfig = { providers: [ provideCopilotKit({ selfManagedAgents: { "support-agent": supportAgent }, }), ], };
</FrontendOnly>
Each key is the `agentId` that chat components and frontend agent APIs use to
address that agent. Self-managed agents use your transport and your security
model. Because the requests don't pass through the CopilotKit runtime, the
runtime's server-side auth, middleware, and routing do not apply. Your agent
endpoint must authenticate and authorize every request.
<Callout type="info">
You can combine `selfManagedAgents` with `runtimeUrl`. Runtime-discovered agents
and self-managed agents coexist; address each by its `agentId`.
</Callout>
## Development: local agents
<FrontendOnly frontend="react">
`agents__unsafe_dev_only` accepts the same shape: a map of `agentId` to
`AbstractAgent`. The name is intentionally loud. Use it only for local
development and prototyping.
```tsx
import { HttpAgent } from "@ag-ui/client";
import { CopilotKit } from "@copilotkit/react-core/v2";
const myAgent = new HttpAgent({ url: "http://localhost:8000" });
<CopilotKit agents__unsafe_dev_only={{ "my-agent": myAgent }}>
<YourApp />
</CopilotKit>;
Reach for it when you're wiring up an agent locally and don't want to stand up a
runtime yet. Don't ship it to production. Switch to selfManagedAgents if you
intend to manage and secure the connection yourself, or move the agent behind the
runtime.
</FrontendOnly>
import { HttpAgent } from "@ag-ui/client";
import { provideCopilotKit } from "@copilotkit/angular";
const localAgent = new HttpAgent({ url: "http://localhost:8000" });
provideCopilotKit({
agents: { "my-agent": localAgent },
})
Use agents only for local development and prototyping. For production,
switch to selfManagedAgents after securing the endpoint, or move the agent
behind the runtime.
</FrontendOnly>
Both sources feed the same client-side agent registry. When both are supplied
they are merged, and selfManagedAgents wins on a key collision:
Supplying agents through either provider option also satisfies the frontend configuration check when at least one local agent is registered.
<FrontendOnly frontend="react"> You won't get the `Missing required prop: 'runtimeUrl' or 'publicApiKey' or 'publicLicenseKey'` error; see the [error reference](/troubleshooting/error-reference). </FrontendOnly>selfManagedAgents | Local agents | |
|---|---|---|
| Intended for | Production, agents you manage | Local dev / prototyping |
| Auth | Your responsibility | Your responsibility |
| Runtime middleware / routing | Not applied | Not applied |
| Precedence on collision | Wins | Overridden by selfManagedAgents |
AbstractAgent / HttpAgent interface these options accept.