Interface AgentSessionOpener
- Functional Interface:
- This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.
LocalSessionCache to lazily open an AgentSession.
Production wiring chooses one of two paths:
WebAgentSessionManagerBuilder.sessionFactory(...)— adaptsAgentSessionFactory.open(ConversationId, String, AgentSessionOptions)into this opener; the manager extracts the agent name fromAgentExecutionContextId.agentName()for the factory call.OpenAttributesflowing through is ignored. This is the simple-case path used by aimon-cli and the example modules.WebAgentSessionManagerBuilder.sessionOpener(...)— supplies a caller-defined opener directly so the implementation can read application-level attributes (e.g., tenant id, organization unit) from theOpenAttributesthat the caller attached to theWebSubmitRequest.
Tests can supply a fake opener to substitute controllable AgentSession instances without standing up a real
OrcaAgentExecutor.
AgentExecutionContext lifecycle (IMPORTANT)
AgentExecutionContext is agent-scoped (one instance per (Agent, discriminator);
see docs/design/agent-execution-context-rescoping.md). The AgentExecutionContextId threaded into
each open(at.aimon.core.agent.conversation.ConversationId, at.aimon.core.agent.AgentExecutionContextId, at.aimon.core.agent.session.AgentSessionOptions, at.aimon.core.agent.session.OpenAttributes) call is derived by the manager from WebSubmitRequest.agentRef and an optional
WebSubmitRequest.contextDiscriminator; the opener's job is to look up the matching pre-registered
context and bind it to a fresh AgentSession, not to register one lazily. Implementations must
not create a fresh AgentExecutionContext per open(at.aimon.core.agent.conversation.ConversationId, at.aimon.core.agent.AgentExecutionContextId, at.aimon.core.agent.session.AgentSessionOptions, at.aimon.core.agent.session.OpenAttributes) call. The application must register the
context once at bootstrap via OrcaAgentExecutionContextManager.getOrCreateContext(bundle, ...) (optionally
with a discriminator) and reuse the same instance for every cache miss.
The returned AgentSession.close() does not close the AgentExecutionContext. Closing the context is
the application owner's responsibility and must happen only at agent removal or application shutdown — typically
via OrcaAgentExecutionContextManager#destroyContext(id). Neither this opener nor
WebAgentSessionManager#close() closes those agent-scoped resources, so MCP clients leak if the owner
forgets.
Canonical implementation
{
@code
AgentSession open(ConversationId convId, AgentExecutionContextId ctxId, AgentSessionOptions options,
OpenAttributes attrs) {
AgentExecutionContext ctx = contextRegistry.get(ctxId)
.orElseThrow(() -> new IllegalStateException("AEC not bootstrapped for " + ctxId));
// attrs carries any additional caller-domain metadata (ops.agentId, ops.ouId, ...).
return sessionFactory.open(convId, ctx, options);
}
}
Each (agent, discriminator) pair must be registered once at bootstrap (via
OrcaAgentExecutionContextManager.getOrCreateContext(bundle, discriminator, ...)) before the first submit
that needs it; the opener does not register lazily.
Re-open semantics
The opener is invoked on cache miss only. While a session is cached on the holder node, subsequent submits with
different OpenAttributes have no effect on the open session. See OpenAttributes for the full
contract.
-
Method Summary
Modifier and TypeMethodDescriptiondefault at.aimon.core.agent.session.AgentSessionopen(at.aimon.core.agent.conversation.ConversationId conversationId, at.aimon.core.agent.AgentExecutionContextId contextId, at.aimon.core.agent.session.AgentSessionOptions options) Convenience overload that delegates toopen(ConversationId, AgentExecutionContextId, AgentSessionOptions, OpenAttributes)withOpenAttributes.empty().at.aimon.core.agent.session.AgentSessionopen(at.aimon.core.agent.conversation.ConversationId conversationId, at.aimon.core.agent.AgentExecutionContextId contextId, at.aimon.core.agent.session.AgentSessionOptions options, at.aimon.core.agent.session.OpenAttributes openAttributes) Opens a session bound toconversationIdandcontextId, usingopenAttributesas the caller-provided attribute channel.
-
Method Details
-
open
at.aimon.core.agent.session.AgentSession open(at.aimon.core.agent.conversation.ConversationId conversationId, at.aimon.core.agent.AgentExecutionContextId contextId, at.aimon.core.agent.session.AgentSessionOptions options, at.aimon.core.agent.session.OpenAttributes openAttributes) Opens a session bound toconversationIdandcontextId, usingopenAttributesas the caller-provided attribute channel.- Parameters:
conversationId- the conversation (must not be null)contextId- the agent-scoped execution context id to bind on first open (must not be null). Derived by the manager fromWebSubmitRequest.agentRefand an optionalWebSubmitRequest.contextDiscriminatorviaAgentExecutionContextId.fromName(String, String).options- session options (must not be null)openAttributes- caller-provided attributes;OpenAttributes.empty()when the caller did not attach any (must not be null)- Returns:
- the opened session (never null)
-
open
default at.aimon.core.agent.session.AgentSession open(at.aimon.core.agent.conversation.ConversationId conversationId, at.aimon.core.agent.AgentExecutionContextId contextId, at.aimon.core.agent.session.AgentSessionOptions options) Convenience overload that delegates toopen(ConversationId, AgentExecutionContextId, AgentSessionOptions, OpenAttributes)withOpenAttributes.empty().Provided so simple callers (and adapters from
AgentSessionFactory) can ignore the attribute channel entirely.- Parameters:
conversationId- the conversation (must not be null)contextId- the agent-scoped execution context id (must not be null)options- session options (must not be null)- Returns:
- the opened session (never null)
-