类 AgentBase
- 所有已实现的接口:
Agent,CallableAgent,ObservableAgent,StreamableAgent
- 直接已知子类:
ReActAgent,UserAgent
This class provides common functionality for agents including basic hook integration, MsgHub subscriber management, interrupt handling, tracing, and state management through StateModule. It does NOT manage memory - that is the responsibility of specific agent implementations like ReActAgent.
Design Philosophy:
- AgentBase provides infrastructure (hooks, subscriptions, interrupt, state) but not domain logic
- Memory management is delegated to concrete agents that need it (e.g., ReActAgent)
- State management implements StateModule interface
- Interrupt mechanism uses reactive patterns: subclasses call checkInterruptedAsync() at appropriate checkpoints, which propagates InterruptedException through Mono chain
- Observe pattern: agents can receive messages without generating a reply
Thread Safety:
Agent instances are NOT designed for concurrent execution. A single agent instance should not
be invoked concurrently from multiple threads (e.g., calling call() or stream()
simultaneously). The hooks list is mutable and modified during streaming operations without
synchronization, which is safe only under single-threaded execution per agent instance.
Interrupt Mechanism:
// External call to interrupt
agent.interrupt(userMsg);
// Inside agent's Mono chain, at checkpoints:
return checkInterruptedAsync()
.then(doWork())
.flatMap(result -> checkInterruptedAsync().thenReturn(result));
// AgentBase.call() catches the exception:
.onErrorResume(error -> {
if (error instanceof InterruptedException) {
return handleInterrupt(context, msg);
}
...
});
-
字段概要
字段修饰符和类型字段说明static final StringReactor Context key carrying the per-call scope object returned bybeforeAgentExecution(List, RuntimeContext).static final StringReactor Context key carrying the caller-supplied per-callRuntimeContext.static final StringReactor Context key carrying this call's graceful-shutdownrequestId(issued byGracefulShutdownManager.registerRequest(io.agentscope.core.agent.Agent)). -
构造器概要
构造器构造器说明Constructor for AgentBase.Constructor for AgentBase.已过时。Constructor for AgentBase with hooks. -
方法概要
修饰符和类型方法说明protected voidAdd a hook to this agent dynamically.static voidaddSystemHook(Hook hook) protected voidInvoked inMono.usingcleanup, before clearing the running state.protected ObjectbeforeAgentExecution(List<Msg> msgs, RuntimeContext rc) Invoked at the start of acall/ stream-backed call, afteracquireExecution()and before any hooks.protected voidPushesctxto allRuntimeContextAwarehooks registered for this agent.final reactor.core.publisher.Mono<Msg> Process a list of input messages and generate a response with hook execution.final reactor.core.publisher.Mono<Msg> Process multiple input messages and generate structured output with hook execution.final reactor.core.publisher.Mono<Msg> Process multiple input messages and generate structured output with hook execution.protected reactor.core.publisher.Mono<Msg> callInternal(List<Msg> msgs, RuntimeContext context, Function<List<Msg>, reactor.core.publisher.Mono<Msg>> doCallFn) Extension point called by everycall()overload, allowing subclasses to wrap the entire invocation in additional middleware (e.g. theonAgentchain inReActAgent).protected ObjectReturns a key that serializes concurrent calls sharing it: calls with an equal, non-null key run one-at-a-time in FIFO order, while calls with different keys (or anullkey) run concurrently.protected reactor.core.publisher.Mono<Void> 已过时。No longer needed; ReActAgent uses per-session InterruptControl.protected voidconsumeSystemMsgAfterPreCall(Msg systemMsg, Object callScope) Called afterPreCallEventhooks have run, with the final system message value.protected abstract reactor.core.publisher.Mono<Msg> Internal implementation for processing multiple input messages.protected reactor.core.publisher.Mono<Msg> Internal implementation for processing multiple messages with structured output.protected reactor.core.publisher.Mono<Msg> Internal implementation for processing multiple messages with structured output.protected reactor.core.publisher.Mono<Void> Observe a message without generating a reply.final StringGet the unique identifier for this agent.Returns the agent's mutable runtime state, ornullif this agent type does not maintain anAgentState.final StringGet the description of this agent.getHooks()Get the list of hooks for this agent.protected AtomicBoolean已过时。No-op stub.protected InterruptSource已过时。Returns USER.final StringgetName()Get the name of this agent.Returns the current per-callRuntimeContext, ornullwhen the agent keeps no per-call scope.Get hooks sorted by priority (lower value = higher priority).intGet the total number of subscribers across all MsgHubs.protected abstract reactor.core.publisher.Mono<Msg> handleInterrupt(InterruptContext context, Msg... originalArgs) Handle an interruption that occurred during execution.booleanCheck if this agent has any subscribers.void已过时。Subclasses should implement per-session interrupt via RuntimeContext.voidinterrupt(InterruptSource source) 已过时。Subclasses should implement per-session interrupt via RuntimeContext.void已过时。Subclasses should implement per-session interrupt via RuntimeContext.final boolean已过时。No longer enforced; per-session serialization handles concurrency.final reactor.core.publisher.Mono<Void> Observe a single message without generating a reply.final reactor.core.publisher.Mono<Void> Observe multiple messages without generating a reply.protected voidremoveHook(Hook hook) Remove a hook from this agent dynamically.voidremoveSubscribers(String hubId) Remove all subscribers for a specific MsgHub.static voidremoveSystemHook(Hook hook) protected void已过时。No-op; per-session interrupt state is managed by AgentState.interruptControl().voidresetSubscribers(String hubId, List<AgentBase> subscribers) Reset the subscriber list for a specific MsgHub.protected reactor.core.publisher.Mono<Msg> Sharedcall()lifecycle: acquire execution, then (insidedeferContextualso the caller-suppliedRuntimeContextis read per-subscription) runbeforeAgentExecution(List, RuntimeContext)(which returns this call's per-call scope), carry that scope on the Reactor Context, and run the preCall → doCall → postCall chain with error handling, releasing execution on terminate.protected reactor.core.publisher.Mono<Msg> seedSystemMsg(Object callScope) Returns the initial system message to seed intoPreCallEventbefore hooks run.protected AgentStatestateForCall(Object callScope) Returns theAgentStatewhose conversation buffer should seed the pre-call memory snapshot for this invocation.reactor.core.publisher.Flux<Event> stream(List<Msg> msgs, StreamOptions options) 已过时, 待删除: 此 API 元素将从以后的版本中删除。since 2.0.0, for removal.reactor.core.publisher.Flux<Event> stream(List<Msg> msgs, StreamOptions options, com.fasterxml.jackson.databind.JsonNode schema) 已过时, 待删除: 此 API 元素将从以后的版本中删除。since 2.0.0, for removal.reactor.core.publisher.Flux<Event> stream(List<Msg> msgs, StreamOptions options, Class<?> structuredModel) 已过时, 待删除: 此 API 元素将从以后的版本中删除。since 2.0.0, for removal.toString()protected voidClears theRuntimeContextpreviously pushed to allRuntimeContextAwarehooks.从类继承的方法 java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait从接口继承的方法 io.agentscope.core.agent.Agent
getToolkit
-
字段详细资料
-
CALL_SCOPE_KEY
Reactor Context key carrying the per-call scope object returned bybeforeAgentExecution(List, RuntimeContext). Agents that maintain per-call state (e.g.ReActAgent'sCallExecution) read it back from the Context indoCall(java.util.List<io.agentscope.core.message.Msg>)/handleInterrupt(io.agentscope.core.interruption.InterruptContext, io.agentscope.core.message.Msg...)so concurrent calls on one instance never share mutable per-call state.- 另请参阅:
-
RUNTIME_CONTEXT_KEY
Reactor Context key carrying the caller-supplied per-callRuntimeContext. Set by thecall(msgs, context)/stream(..., context)/streamEvents(msgs, context)overloads viacontextWrite, and read back here at call entry so the RC flows per-subscription (concurrency-safe) instead of through a shared instance field.- 另请参阅:
-
SHUTDOWN_REQUEST_ID_KEY
Reactor Context key carrying this call's graceful-shutdownrequestId(issued byGracefulShutdownManager.registerRequest(io.agentscope.core.agent.Agent)). Threaded per-subscription so shutdown interrupt/save target the exact in-flight call even when one agent instance serves many concurrent calls — keying shutdown tracking by agent id would otherwise collapse concurrent calls into a single entry.- 另请参阅:
-
-
构造器详细资料
-
AgentBase
Constructor for AgentBase.- 参数:
name- Agent name
-
AgentBase
Constructor for AgentBase.- 参数:
name- Agent namedescription- Agent description
-
AgentBase
@Deprecated public AgentBase(String name, String description, boolean checkRunning, List<Hook> hooks) 已过时。UseAgentBase(String, String, List)instead. -
AgentBase
Constructor for AgentBase with hooks.- 参数:
name- Agent namedescription- Agent descriptionhooks- List of hooks for monitoring/intercepting execution
-
-
方法详细资料
-
getAgentId
从接口复制的说明:AgentGet the unique identifier for this agent.- 指定者:
getAgentId在接口中Agent- 返回:
- Agent ID
-
getName
从接口复制的说明:AgentGet the name of this agent. -
getDescription
从接口复制的说明:AgentGet the description of this agent.- 指定者:
getDescription在接口中Agent- 返回:
- Agent description
-
isCheckRunning
已过时。No longer enforced; per-session serialization handles concurrency. -
call
Process a list of input messages and generate a response with hook execution.Tracing data will be captured once telemetry is enabled.
- 指定者:
call在接口中CallableAgent- 参数:
msgs- Input messages- 返回:
- Response message
-
callInternal
protected reactor.core.publisher.Mono<Msg> callInternal(List<Msg> msgs, RuntimeContext context, Function<List<Msg>, reactor.core.publisher.Mono<Msg>> doCallFn) Extension point called by everycall()overload, allowing subclasses to wrap the entire invocation in additional middleware (e.g. theonAgentchain inReActAgent).The default implementation attaches
contextto the Reactor Context (when non-null) and delegates straight torunLifecycle(java.util.List<io.agentscope.core.message.Msg>, java.util.function.Function<java.util.List<io.agentscope.core.message.Msg>, reactor.core.publisher.Mono<io.agentscope.core.message.Msg>>). Subclasses that override this method must eventually invokerunLifecycle(msgs, doCallFn)to run the standard lifecycle (shutdown guard, serialization gate, pre/post hooks, tracing).- 参数:
msgs- input messagescontext- caller-supplied per-callRuntimeContext, ornulldoCallFn- the concrete call implementation (doCall(java.util.List<io.agentscope.core.message.Msg>)or a structured-output variant)- 返回:
- response message
-
runLifecycle
protected reactor.core.publisher.Mono<Msg> runLifecycle(List<Msg> msgs, Function<List<Msg>, reactor.core.publisher.Mono<Msg>> doCallFn) Sharedcall()lifecycle: acquire execution, then (insidedeferContextualso the caller-suppliedRuntimeContextis read per-subscription) runbeforeAgentExecution(List, RuntimeContext)(which returns this call's per-call scope), carry that scope on the Reactor Context, and run the preCall → doCall → postCall chain with error handling, releasing execution on terminate. -
callSerializationKey
Returns a key that serializes concurrent calls sharing it: calls with an equal, non-null key run one-at-a-time in FIFO order, while calls with different keys (or anullkey) run concurrently. The default returnsnull(no serialization).ReActAgentreturns its(userId, sessionId)slot key so same-session calls do not corrupt shared conversation state while distinct sessions run in parallel.- 参数:
rc- the caller-supplied per-callRuntimeContext(may benull)- 返回:
- the serialization key, or
nullto run without serialization
-
call
Process multiple input messages and generate structured output with hook execution.Tracing data will be captured once telemetry is enabled.
- 指定者:
call在接口中CallableAgent- 参数:
msgs- Input messagesstructuredOutputClass- Class defining the structure of the output- 返回:
- Response message with structured data in metadata
-
call
public final reactor.core.publisher.Mono<Msg> call(List<Msg> msgs, com.fasterxml.jackson.databind.JsonNode schema) Process multiple input messages and generate structured output with hook execution.Tracing data will be captured once telemetry is enabled.
- 指定者:
call在接口中CallableAgent- 参数:
msgs- Input messagesschema- com.fasterxml.jackson.databind.JsonNode instance defining the structure of the output- 返回:
- Response message with structured data in metadata
-
doCall
Internal implementation for processing multiple input messages. Subclasses must implement their specific logic here.- 参数:
msgs- Input messages- 返回:
- Response message
-
doCall
Internal implementation for processing multiple messages with structured output. Subclasses that support structured output must override this method. Default implementation throws UnsupportedOperationException.- 参数:
msgs- Input messagesstructuredOutputClass- Class defining the structure- 返回:
- Response message with structured data in metadata
-
doCall
protected reactor.core.publisher.Mono<Msg> doCall(List<Msg> msgs, com.fasterxml.jackson.databind.JsonNode outputSchema) Internal implementation for processing multiple messages with structured output. Subclasses that support structured output must override this method. Default implementation throws UnsupportedOperationException.- 参数:
msgs- Input messagesoutputSchema- com.fasterxml.jackson.databind.JsonNode instance defining the structure- 返回:
- Response message with structured data in metadata
-
addSystemHook
-
removeSystemHook
-
interrupt
已过时。Subclasses should implement per-session interrupt via RuntimeContext.从接口复制的说明:AgentInterrupt the current agent execution. This method sets an interrupt flag that will be checked by the agent at appropriate checkpoints during execution. The interruption is cooperative and may not take effect immediately. -
interrupt
已过时。Subclasses should implement per-session interrupt via RuntimeContext.从接口复制的说明:AgentInterrupt the current agent execution with a user message. This method sets an interrupt flag and associates a user message with the interruption. The interruption is cooperative and may not take effect immediately. -
interrupt
已过时。Subclasses should implement per-session interrupt via RuntimeContext. -
checkInterruptedAsync
已过时。No longer needed; ReActAgent uses per-session InterruptControl. -
resetInterruptFlag
已过时。No-op; per-session interrupt state is managed by AgentState.interruptControl(). -
getInterruptFlag
已过时。No-op stub. -
getInterruptSource
已过时。Returns USER. Per-session interrupt source is on AgentState.interruptControl(). -
doObserve
Observe a message without generating a reply. This allows agents to receive messages from other agents or the environment without responding. It's commonly used in multi-agent collaboration scenarios.Common implementation patterns:
- Stateless agents: Empty implementation if observation is not needed
- Stateful agents: Store message in memory/context for use in future calls
- Collaborative agents: Update shared knowledge or trigger side effects
- 参数:
msg- The message to observe- 返回:
- Mono that completes when observation is done
-
handleInterrupt
protected abstract reactor.core.publisher.Mono<Msg> handleInterrupt(InterruptContext context, Msg... originalArgs) Handle an interruption that occurred during execution. Subclasses must implement this to provide recovery logic based on the interrupt context.Implementation guidance:
- Simple agents: Return a basic interrupt acknowledgment message
- Complex agents: Generate a summary including any pending operations or partial results
- Stateful agents: Ensure state is saved appropriately before returning
- 参数:
context- The interrupt context containing metadata about the interruptionoriginalArgs- The original arguments passed to the call() method (empty, single Msg, or List)- 返回:
- Recovery message to return to the user
-
getAgentState
Returns the agent's mutable runtime state, ornullif this agent type does not maintain anAgentState.- 指定者:
getAgentState在接口中Agent
-
getRuntimeContext
Returns the current per-callRuntimeContext, ornullwhen the agent keeps no per-call scope. The base implementation returnsnull; agents with per-call state (e.g.ReActAgent) override this to return their active call scope's context. Because the value is sourced from the agent's most-recently-activated scope, under concurrent calls on one instance this reflects the latest call — middlewares/tools that need their own call's context should read it from the per-subscriptionRuntimeContextthey are handed. -
beforeAgentExecution
Invoked at the start of acall/ stream-backed call, afteracquireExecution()and before any hooks.ReActAgentuses this to activate the per-call session slot from the suppliedRuntimeContextand returns the freshly-built per-call scope object, which is carried on the Reactor Context underCALL_SCOPE_KEY. Returning the scope here (rather than via a separate accessor) avoids any window in which a concurrent call could overwrite a shared field between construction and capture.- 参数:
msgs- the messages passed by the caller tocall()rc- the caller-supplied per-callRuntimeContext, ornullwhen none was provided (read from the Reactor Context, so concurrency-safe)- 返回:
- this call's per-call scope object, or
nullif this agent type keeps none
-
afterAgentExecution
protected void afterAgentExecution()Invoked inMono.usingcleanup, before clearing the running state. Pairs withbeforeAgentExecution(List, RuntimeContext). The default is a no-op. -
bindRuntimeContextToHooks
Pushesctxto allRuntimeContextAwarehooks registered for this agent. The per-callRuntimeContextitself is no longer stored on a shared instance field; it lives on the agent's per-call scope (seegetRuntimeContext()). -
unbindRuntimeContextFromHooks
protected void unbindRuntimeContextFromHooks()Clears theRuntimeContextpreviously pushed to allRuntimeContextAwarehooks. -
getHooks
Get the list of hooks for this agent. Protected to allow subclasses to access hooks for custom notification logic.- 返回:
- List of hooks
-
addHook
Add a hook to this agent dynamically.Hooks can be added during agent execution to provide temporary functionality. This is commonly used for structured output handling or other short-lived behaviors.
- 参数:
hook- The hook to add
-
removeHook
Remove a hook from this agent dynamically.Hooks should be removed when they are no longer needed to avoid memory leaks and unintended side effects.
- 参数:
hook- The hook to remove
-
getSortedHooks
Get hooks sorted by priority (lower value = higher priority). Hooks with the same priority maintain registration order.- 返回:
- Sorted list of hooks
-
seedSystemMsg
Returns the initial system message to seed intoPreCallEventbefore hooks run.The default implementation returns
null. Subclasses (e.g.ReActAgent) override this to build a system message from their configuredsysPrompt.- 参数:
callScope- the per-call scope captured at call entry (may benull); lets subclasses resolve the call'sRuntimeContextfor system-prompt middlewares without reading a shared instance field- 返回:
- the seed system message; empty Mono if none
-
stateForCall
Returns theAgentStatewhose conversation buffer should seed the pre-call memory snapshot for this invocation. The default reads the agent-levelgetAgentState(); subclasses with per-call scope (e.g.ReActAgent) return the scope's session state so the snapshot is concurrency-correct.- 参数:
callScope- the per-call scope captured at call entry (may benull)- 返回:
- the state to snapshot, or
nullif none
-
consumeSystemMsgAfterPreCall
Called afterPreCallEventhooks have run, with the final system message value.The default implementation is a no-op. Subclasses (e.g.
ReActAgent) override this to persist the system message into a per-callAtomicReferenceso it is available to subsequent events (PreReasoningEvent,PreSummaryEvent).- 参数:
systemMsg- the system message produced by all PreCall hooks (may be null)callScope- the per-call scope captured at call entry (seebeforeAgentExecution(List, RuntimeContext)); may benull
-
removeSubscribers
Remove all subscribers for a specific MsgHub. This method is typically called when a MsgHub is being destroyed or reset. After calling this method, the agent will no longer receive messages from the specified hub.- 参数:
hubId- MsgHub identifier
-
resetSubscribers
Reset the subscriber list for a specific MsgHub. This replaces any existing subscribers for the given hub with the new list. Typically called by MsgHub when the subscription topology changes.- 参数:
hubId- MsgHub identifiersubscribers- New list of subscribers (will be copied)
-
hasSubscribers
public boolean hasSubscribers()Check if this agent has any subscribers. Subscribers are agents that will receive messages published through MsgHub.- 返回:
- True if agent has one or more subscribers
-
getSubscriberCount
public int getSubscriberCount()Get the total number of subscribers across all MsgHubs. Subscribers are agents that will receive messages published through MsgHub.- 返回:
- Total count of subscribers
-
observe
Observe a single message without generating a reply. This is the public API that delegates to doObserve implementation.- 指定者:
observe在接口中ObservableAgent- 参数:
msg- Message to observe- 返回:
- Mono that completes when observation is done
-
observe
Observe multiple messages without generating a reply. This is the public API that delegates to doObserve implementation.- 指定者:
observe在接口中ObservableAgent- 参数:
msgs- Messages to observe- 返回:
- Mono that completes when all observations are done
-
stream
@Deprecated(since="2.0.0", forRemoval=true) public reactor.core.publisher.Flux<Event> stream(List<Msg> msgs, StreamOptions options) 已过时, 待删除: 此 API 元素将从以后的版本中删除。since 2.0.0, for removal. UseReActAgent#streamEvents(List)for the fine-grainedAgentEventstream.Stream with multiple input messages.- 指定者:
stream在接口中StreamableAgent- 参数:
msgs- Input messagesoptions- Stream configuration options- 返回:
- Flux of events emitted during execution
-
stream
@Deprecated(since="2.0.0", forRemoval=true) public reactor.core.publisher.Flux<Event> stream(List<Msg> msgs, StreamOptions options, Class<?> structuredModel) 已过时, 待删除: 此 API 元素将从以后的版本中删除。since 2.0.0, for removal. UseReActAgent#streamEvents(...)for the fine-grainedAgentEventstream.Stream with multiple input messages.- 指定者:
stream在接口中StreamableAgent- 参数:
msgs- Input messagesoptions- Stream configuration optionsstructuredModel- Optional class defining the structure- 返回:
- Flux of events emitted during execution
-
stream
@Deprecated(since="2.0.0", forRemoval=true) public reactor.core.publisher.Flux<Event> stream(List<Msg> msgs, StreamOptions options, com.fasterxml.jackson.databind.JsonNode schema) 已过时, 待删除: 此 API 元素将从以后的版本中删除。since 2.0.0, for removal. UseReActAgent#streamEvents(...)for the fine-grainedAgentEventstream.Stream with multiple input messages using a JSON schema.- 指定者:
stream在接口中StreamableAgent- 参数:
msgs- Input messagesoptions- Stream configuration optionsschema- JSON schema defining the structure of the response- 返回:
- Flux of events emitted during execution
-
toString
-
AgentBase(String, String, List)instead.