Asking
A middleware that asks typed questions of type Q and takes answers of type Ans, as org.llm4s.agent.graph.tool.AgentTool.Asking does for a tool: it suspends the run for a reviewer - to approve or edit an answer, or to supply missing information - instead of only blocking or failing.
A hook asks by returning ask - from beforeAgent, afterAgent or wrapModelCall - or askAbout from wrapToolCall. The run suspends at the end of the superstep with a question of its own, keyed by the asking task's interrupt id like any other, so several pending questions are answered together or one at a time. The answer is decoded as Ans when the run is resumed: one that does not decode is refused, the thread unchanged.
Once answered, the hook's whole stack runs again from the outermost middleware - nothing about a stack's position is checkpointed, as for approvals - and answered gives this middleware its question and answer, so it continues instead of asking again. Answers given earlier in the same stack run are kept while it runs again, so two asking middleware in one stack each ask once. A middleware outside the asking one therefore runs twice, and must not depend on running once.
What runs again is the asking task: beforeAgent re-runs the turn's input (nothing of the turn is stored while it waits), afterAgent the final answer, wrapToolCall the tool call (its arguments checked again), and wrapModelCall the model call - so a model wrapper that asks after calling next calls the model again once answered, unless it returns a completion of its own (the calls made before asking are counted in the thread's usage, and announced, while the question waits). A question from a tool wrapper while the tool continues after its own question is refused, as the call's error result.
Attributes
- Graph
-
- Supertypes
- Known subtypes
Members list
Value members
Concrete methods
This middleware's question and its answer, when its hook runs again after a resume; None before.
This middleware's question and its answer, when its hook runs again after a resume; None before.
Attributes
Suspends the run with question; return it as the result of beforeAgent, afterAgent or wrapModelCall. A question that does not encode is that Left instead.
Suspends the run with question; return it as the result of beforeAgent, afterAgent or wrapModelCall. A question that does not encode is that Left instead.
Attributes
Suspends the tool call with question; return it as the result of wrapToolCall.
Suspends the tool call with question; return it as the result of wrapToolCall.
Attributes
Inherited methods
Sees the run's final answer: returns it, possibly changed, with an update to this middleware's writes, or Left to block the run.
Sees the run's final answer: returns it, possibly changed, with an update to this middleware's writes, or Left to block the run.
Attributes
- Inherited from:
- AgentMiddleware
Sees the run's input before anything else runs: returns it, possibly changed, with an update to this middleware's writes that the turn's first model call sees, or Left to block the run.
Sees the run's input before anything else runs: returns it, possibly changed, with an update to this middleware's writes that the turn's first model call sees, or Left to block the run.
Attributes
- Inherited from:
- AgentMiddleware
Where this middleware must run relative to other, when both are present; None, the default, when it does not matter. A requirement is checked, never arranged: MiddlewareStack.of - so AgentBuilder.build() - refuses a stack in which this middleware does not run outside other, and a Placement.OutsideAtBoundary is checked across an agent family too. Register the two in the right order, or name other in runsBefore. Name other by its type: ids are configurable.
Where this middleware must run relative to other, when both are present; None, the default, when it does not matter. A requirement is checked, never arranged: MiddlewareStack.of - so AgentBuilder.build() - refuses a stack in which this middleware does not run outside other, and a Placement.OutsideAtBoundary is checked across an agent family too. Register the two in the right order, or name other in runsBefore. Name other by its type: ids are configurable.
Attributes
- Inherited from:
- AgentMiddleware
Content for the system prompt of each model request: collected before every model step from the committed state, in stack order, and never stored. Each middleware bounds its own; the agent bounds them all together (maxPromptSectionTokens). Left fails the run.
Content for the system prompt of each model request: collected before every model step from the committed state, in stack order, and never stored. Each middleware bounds its own; the agent bounds them all together (maxPromptSectionTokens). Left fails the run.
Attributes
- Inherited from:
- AgentMiddleware
Middleware this one must run inside of (be wrapped by); each must be registered in the same stack.
Middleware this one must run inside of (be wrapped by); each must be registered in the same stack.
Attributes
- Inherited from:
- AgentMiddleware
Middleware this one must run outside of (wrap); each must be registered in the same stack.
Middleware this one must run outside of (wrap); each must be registered in the same stack.
Attributes
- Inherited from:
- AgentMiddleware
Tools this middleware contributes; they join the loop's tool set and are validated like any other.
Tools this middleware contributes; they join the loop's tool set and are validated like any other.
Attributes
- Inherited from:
- AgentMiddleware
Wraps one model call. A wrapper may rewrite the request (inject a note, filter tools), call next more than once (retry, fallback), transform its response, add an update to its writes (ModelResponse.addUpdate), or return Left, which fails the run. Only an AgentMiddleware.Asking wrapper suspends, by asking its question. Every call next makes is counted in the thread's usage, whichever response the wrapper returns.
Wraps one model call. A wrapper may rewrite the request (inject a note, filter tools), call next more than once (retry, fallback), transform its response, add an update to its writes (ModelResponse.addUpdate), or return Left, which fails the run. Only an AgentMiddleware.Asking wrapper suspends, by asking its question. Every call next makes is counted in the thread's usage, whichever response the wrapper returns.
Filtering ModelRequest.tools shapes what the model is offered and is not a permission control: a tool the model calls anyway still runs through wrapToolCall, where denial belongs.
Attributes
- Inherited from:
- AgentMiddleware
Wraps one tool call, after its arguments were validated. A wrapper denies with ToolOutcome.Error("Denied: ..."), asks for approval with NeedsApproval(reason) (unless context.approved), fails the run with Fatal, and short-circuits by not calling next. It may call next more than once (retry) and transform the outcome next returns.
Wraps one tool call, after its arguments were validated. A wrapper denies with ToolOutcome.Error("Denied: ..."), asks for approval with NeedsApproval(reason) (unless context.approved), fails the run with Fatal, and short-circuits by not calling next. It may call next more than once (retry) and transform the outcome next returns.
Attributes
- Inherited from:
- AgentMiddleware
The state keys this middleware's hooks may write: an update from beforeAgent, wrapModelCall or afterAgent, or one wrapToolCall adds to a Success. A hook's write to any other key fails the run.
The state keys this middleware's hooks may write: an update from beforeAgent, wrapModelCall or afterAgent, or one wrapToolCall adds to a Success. A hook's write to any other key fails the run.
Attributes
- Inherited from:
- AgentMiddleware
Inherited and Abstract methods
This middleware's identifier, unique in its stack; must match [a-zA-Z0-9_-]{1,64}.
This middleware's identifier, unique in its stack; must match [a-zA-Z0-9_-]{1,64}.
Attributes
- Inherited from:
- AgentMiddleware