Why a custom executor

Reasons: (1) unify with your service's existing thread pool for cost tracking; (2) inject OpenTelemetry spans at the lowest level; (3) apply agent-wide rate limits or bulkheads.

Advertisement

The Executor interface

The runtime asks the executor to run tasks. It provides one method — submit(Runnable) — and expects work to eventually run.

public interface AgentExecutor {
   CompletableFuture submit(Callable task);
}
Advertisement

Middleware pattern

You can compose middleware around the default executor rather than replacing it entirely.

AgentExecutor traced = TracingMiddleware.wrap(
    RateLimitMiddleware.wrap(
        AgentExecutor.defaults(),
        rateLimiter
    ),
    tracer
);
runtime.setExecutor(traced);