style: rewrap comments and docs lines lengthened by the previous_messages rename

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
hugocasa
2026-09-15 21:01:41 +02:00
co-authored by Claude Opus 5
parent 88d9bb00eb
commit 7bbd0b65de
5 changed files with 26 additions and 23 deletions
+2 -2
View File
@@ -137,8 +137,8 @@ struct AIAgentArgsRaw {
// nothing runs stateless instead of falling back to the run's memory id.
#[serde(default, deserialize_with = "deserialize_present")]
memory_id: Option<serde_json::Value>,
// Same distinction for an authored previous messages expression: null replaces a legacy manual list with
// no history, where an absent key keeps that list.
// Same distinction for an authored previous messages expression: null replaces a legacy manual
// list with no history, where an absent key keeps that list.
#[serde(default, deserialize_with = "deserialize_present_messages")]
previous_messages: Option<Option<Vec<OpenAIMessage>>>,
enabled_tools: Option<Vec<String>>,
+4 -4
View File
@@ -144,8 +144,8 @@ fn keep_authored_history_args(
/// Reconciles the step's history inputs, the agent's memory policy and the run's memory id, for
/// every shape a flow or agent resource may still carry. Managed memory reads only a memory id, and
/// memory that is off reads only previous messages. Also returns lines for the job log: a step input that
/// went unused, or a policy that remembers ending up stateless.
/// memory that is off reads only previous messages. Also returns lines for the job log: a step
/// input that went unused, or a policy that remembers ending up stateless.
fn resolve_history_source<'a>(
args: &'a AIAgentArgs,
run_memory_id: Option<Uuid>,
@@ -2133,8 +2133,8 @@ mod tests {
}
}
/// Empty previous messages a form leaves on a step never replace a legacy list; an expression does, even
/// when it evaluates to null.
/// Empty previous messages a form leaves on a step never replace a legacy list; an expression
/// does, even when it evaluates to null.
#[test]
fn only_an_expression_can_empty_a_legacy_message_list() {
let run = Uuid::from_u128(1);
+15 -13
View File
@@ -17,10 +17,11 @@ every workspace via the standard cached-resource-type sync, like other built-in
(`windmill-worker/src/ai_executor.rs`): the brain is interpolated, so a nested provider `$res:`
credential resolves automatically.
- The step keeps only the flow-local inputs (`user_message`, `user_attachments`, `enabled_tools`,
and the history inputs `memory_id` and `previous_messages`) in its own `input_transforms`; the brain and
tools stay in the resource (read-only in the step). `enabled_tools` says which of the roster this
step may call, narrowing one use of a shared agent without touching the agent: an absent field
carries every tool, a list carries the ones it names, and an empty list carries none.
and the history inputs `memory_id` and `previous_messages`) in its own `input_transforms`; the
brain and tools stay in the resource (read-only in the step). `enabled_tools` says which of the
roster this step may call, narrowing one use of a shared agent without touching the agent: an
absent field carries every tool, a list carries the ones it names, and an empty list carries
none.
- The agent carries its tools' default input bindings verbatim as authored (static, AI-filled,
or flow expressions), so saving round-trips losslessly. Each host flow overrides what it
needs: `tool_inputs` stores per-tool overrides (a diff from the resource tool's own
@@ -53,20 +54,21 @@ which memory it is:
webhooks, evals and plain runs pass no id and run stateless.
- **Step: history inputs.** Flow-local, so they stay on a linked step. Each is read in one memory
state only, and the editor offers it only there, the memory id behind a *Custom* toggle that
writes the key only once it is on. With managed memory on, `memory_id` overrides
the run's id, hashed the same way: a fixed value is one memory shared by every run, an expression
such as `flow_input.customer_id` one memory per key, and an expression that evaluates to nothing
runs stateless rather than falling back to the run's id. With memory off, `previous_messages` supplies the
history itself. The editor never seeds a placeholder for either, because a present key is the
writes the key only once it is on. With managed memory on, `memory_id` overrides the run's id,
hashed the same way: a fixed value is one memory shared by every run, an expression such as
`flow_input.customer_id` one memory per key, and an expression that evaluates to nothing runs
stateless rather than falling back to the run's id. With memory off, `previous_messages` supplies
the history itself. The editor never seeds a placeholder for either, because a present key is the
step's choice, and a static empty value reads as unset.
The worker reconciles them once per agent invocation, nested agent tools included, in
`resolve_history_source` (`windmill-worker/src/ai_executor.rs`):
1. Memory off, or a legacy `manual` memory: the history is `previous_messages`, else the `manual` list,
else nothing. Memory is neither read nor written, and a step `memory_id` is ignored.
2. Managed memory: a step `previous_messages` is ignored. The memory id is the step's, else the run's, else
a legacy id baked into the `auto` object. With no memory id the agent runs stateless.
1. Memory off, or a legacy `manual` memory: the history is `previous_messages`, else the `manual`
list, else nothing. Memory is neither read nor written, and a step `memory_id` is ignored.
2. Managed memory: a step `previous_messages` is ignored. The memory id is the step's, else the
run's, else a legacy id baked into the `auto` object. With no memory id the agent runs
stateless.
Each ignored input and each stateless fallback is written to the job log.
@@ -7,8 +7,8 @@
* it moves into. */
args: Record<string, any>
chatInputEnabled?: boolean
/** Whether the step's own memory id and previous messages are on this form. A saved agent has neither:
* they belong to each step linking it. */
/** Whether the step's own memory id and previous messages are on this form. A saved agent has
* neither: they belong to each step linking it. */
historyOnStep?: boolean
s3StorageConfigured?: boolean
}
@@ -178,8 +178,9 @@ type AiAgentValue = Extract<FlowModule['value'], { type: 'aiagent' }>
*
* The overlay order is the worker's (`ai_executor.rs`): its linked branch interpolates the whole
* resource brain and only then writes the flow-local inputs (`user_message`, `user_attachments`,
* `enabled_tools`, `memory_id`, `previous_messages`) back from the step's own args. `tool_inputs` stays untouched — the worker overlays it onto the tools in both branches, so
* an inlined step keeps the host flow's tool bindings.
* `enabled_tools`, `memory_id`, `previous_messages`) back from the step's own args. `tool_inputs`
* stays untouched — the worker overlays it onto the tools in both branches, so an inlined step
* keeps the host flow's tool bindings.
*/
export function inlineAgentDraft(value: AiAgentValue, args: AIAgentConfig): AiAgentValue {
const { agent: _agent, ...rest } = value