The editor page opens an agent's evals over itself, as the agent page does, with the unsaved
edits offered to a run; the editor dialog keeps evals as a level of its own. The two pages share
the dialog.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The agent's own settings (path, labels, workspace specific, description) open from a cog as
the flow and script editors' do, laid out as the top of the resource editor. The folder note is
gone.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The path leaves the agent form: the editor dialog opens it as a level, as it does evals, and the
editor page in a drawer. The agent page gains Evals, in a dialog. The page supplies the run
form, keeping it out of the editor the flow editor reaches.
The draft edit gate no longer throws when a focused, changed field is removed: the `change` that
removal fires lands mid-teardown, so the gate opens just after instead.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Drops the agent run-as identity: its storage in the agent value, the backfill, the resolution
on every write, and its handling in export, the CLI, draft and cross-workspace deploys, forks
and the workspace compare. The run endpoint runs as the caller, so an operator or reader runs an
agent with their own access. The editor tells the author of a folder agent that anyone running
it needs access to its AI resource and to what its tools use.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* feat(ai-agent): add autocompacted memory that summarizes older context
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix(ai-agent): compact on final-answer turns and count what a turn appended
Address the pre-push review findings on the compaction path:
- A turn the model answers without a tool call left the agent loop on its first
iteration, so a chat-shaped step never compacted and reloaded the whole
conversation on every later turn. Compaction now also runs after the loop.
- The trigger measured only the last request, so a single large tool result
could carry the next one past the window without ever crossing 80%.
- The summarization call re-sent the usage-tracking request shape on endpoints
the loop had already learned to drop it for.
- The flat 8000-token summary reserve swallowed the whole target on a small
context window, leaving one message in the tail and summarizing the rest.
- A response cut off inside the <analysis> scratchpad was accepted as a summary.
- The chat-mode memory default was a shared object the step form edited in place.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix(ai-agent): keep Anthropic prompt counts and compact once per response
Address the first CI review round on the compaction path:
- Anthropic's streaming parser dropped `message_start`, the only event carrying
the prompt-side counts, so a native Anthropic run reported no input tokens at
all and compaction fell back to a character estimate.
- A loop that exits without issuing another request — a structured-output turn
does — reached the post-loop pass still holding the previous measurement and
compacted a second time, or retried a failure with nothing changed.
- The summarization call inherited the step's `max_completion_tokens`; a low one
truncates the summary inside its scratchpad, which counts as a failure and
disables compaction after three of them.
- A fired trigger that found nothing to summarize said nothing.
- Memory already over the window — a lowered `context_window`, or a step moved
over from `auto` — had no way back, since compaction only ran after an
accepted request. It now also runs once before the first one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix(ai-agent): state the summary's own completion cap and drop the pre-flight pass
- The summarization call asked for no completion cap at all, which is "uncapped"
only on the OpenAI-shaped providers: Anthropic substitutes 64000, over several
Claude models' output ceiling, and Bedrock leaves the model's own small default,
short enough to cut the response off inside its scratchpad. It now asks for the
reserve the split already set aside, raised to the step's cap when that is larger.
- Compaction no longer runs before the first request. The fallbacks the loop learns
from a rejection are not known that early, so on exactly the endpoints that need
them the summarization was malformed by construction: it failed, spent a strike,
and the first agent request still carried the oversized conversation. A memory
already past the window is repaired on the turn after a request the endpoint
accepts, rather than by a pass that cannot succeed there.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix(ai-agent): ask the summary for exactly the room the split reserved
The split scales its reserve down on a small window while the request asked for
a flat 8000, so the two diverged below an 80k window: on a 4k/8k model the cap
alone exceeded the window and every summarization was refused, and on a 20k one
a full-length summary could land the conversation back over the trigger and
compact its own previous summary on the next response. Both now read one
`summary_reserve_tokens`.
The call also no longer inherits the step's reasoning effort. Every provider
counts thinking against that same budget, so a high-effort model could spend the
whole reserve before writing anything and return a summary cut off inside its
scratchpad; the compaction prompt asks for an `<analysis>` block, which is the
reasoning this call needs.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix(ai-agent): charge the compaction budget for tools and the system prompt
The tail budget was the whole target, but a request also carries the system
prompt compaction keeps and the tool definitions, which are not in the message
list at all. On a small window those are most of it: a tail sized to the full
target left the next request back over the trigger, compacting again every
response, and the no-usage estimate missed the tool schemas entirely so it could
fail to trigger at all. Both now account for them.
The reserve also gains a floor. It is the summary's output cap as well as the
room the split leaves, and scaled down without one a small window gave a
structured nine-section summary a few hundred tokens — truncated inside its
scratchpad every time, which is discarded, which switches the mode off after
three.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix(ai-agent): count Gemini's tool-use prompt tokens in an agent step's usage
Gemini splits a tool-using turn's input across `promptTokenCount` and a disjoint
`toolUsePromptTokenCount`, and its thinking apart from `candidatesTokenCount`.
The agent step's parser read only the headline fields, so every tool-using turn
under-reported both — and the compaction trigger, which runs off the reported
prompt, could not see the tool results that grew it. It now goes through the same
helpers the proxy path already used.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix(ai-agent): calibrate the compaction estimate against the measured prompt
Two rounds running, the finding was "the character estimate cannot see input X"
— tool schemas, then S3 attachments, which are short paths in the message list
and whole images by the time a provider counts them. Enumerating those is a list
that only grows, so the estimate is now scaled to the one number that is ground
truth: what the provider charged for the last request. Attachments, tokenizer
drift and whatever comes next fall out of that, because the estimate is only
ever used relative to itself.
Also stop the Gemini helpers turning an absent count into `Some(0)`. Downstream,
absent means "fall back to estimating the conversation" while zero reads as an
empty prompt and would hold the trigger below its threshold for the whole run.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix(ai-agent): charge attachments what they cost and let a heavy short prefix compact
The calibration conserved the conversation's total cost but spread it by
character count, so an attachment — a short S3 path in the message list, a whole
image or PDF once a provider expands it — was charged to the text messages around
it and stayed nearly free in the split. It now carries a nominal cost of its own,
which the calibration corrects a residual on rather than the whole gap.
The four-message minimum also refused exactly the case that fix is for: an
attachment arriving on the first or second turn can pass the trigger before four
removable messages exist, and summarizing even one of them saves most of the
prompt. A prefix worth a quarter of the window is now enough on its own.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix(ai-agent): never summarize a prefix holding only a previous summary
The message-count floor was carrying a second job: a fresh summary sits in a one
or two message prefix, so requiring four declined it. The share threshold added
last commit admits it, and a summary is reserve-sized by construction — so the
post-compaction shape could spend one summarization per response swapping a
summary for another the same size, shrinking nothing and losing fidelity each
time. A previous summary no longer counts towards that threshold.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix(ai-agent): take the context window from the model and drop the estimate calibration
Brings compaction in line with how the AI session does the same job, which had
already answered these three questions.
- The window is looked up from the model. `MODEL_CONTEXT_WINDOWS` in
`windmill-ai/src/model_context.rs` mirrors the session's table in
`copilot/modelConfig.ts`, entry for entry and with the same matching rules;
each side points at the other, since a model added to one and not the other
compacts at two different sizes. A step's `context_window` becomes the
override for what the lookup cannot serve, and chat mode writes none.
- Provider usage is normalized where the provider's quirk is, not at the
consumer. `TokenUsage::with_cache_beside_input` raises `input_tokens` to the
whole prompt for Anthropic and Bedrock, which report their cached prefix
beside it; the OpenAI shape already counts it inside. `prompt_tokens()` is
then just `input_tokens`, rather than inferring the shape from whether a
write count is present.
- The estimator is no longer calibrated against the measured prompt. The
session uses the provider's count when it has one and a chars/4 estimate
otherwise, with nothing in between, and a tail sized a little wrong only
compacts again a turn later.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* feat(ai-agent): summarize memory down to what the database can store
Without an instance object store, memory is a 100KB database row cut
from its oldest message, the summary included, so compaction on a
mainstream model never got to keep anything across runs. A step that
persists there now runs its post-loop compaction pass against the
smaller of the model's window and the cap at chars/4, about 25k tokens:
the loop keeps the whole window, and what is written is a summary plus a
tail that fits. The run logs when that pass summarizes, and how many
messages the write dropped when one still overshoots.
The editor's storage warning on the option is removed: nothing exposes
the instance storage to it, so it keyed on the workspace S3 setting,
which is unrelated to where memory goes.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix(ai-agent): get a complete, billed summary out of every provider
Compaction against the real providers turned up four things the stub
could not: Gemini and OpenAI's reasoning models think by default and
bill it against the same cap the summary must fit in, so the
summarization request now asks them for their least (none, low); an
OpenAI Responses call that hits max_output_tokens ends in
response.incomplete, whose usage the parser dropped, so that
summarization went unbilled; a summary that quotes </summary> when it
describes its own instruction was cut off at the quote, on the agent
step and the AI session alike; and the prefix could end on an unanswered
user message, after which the instruction reads as part of that turn
(Anthropic merges the two outright). The tail now starts on a user
message, and both prompts tell the model the instruction is not part of
the conversation.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix(ai-agent): compact down to half the window, on the agent step and the AI session
The gap between the 80% trigger and the target is what one compaction
buys, and every summarization request carries most of the window. At a
70% target a 128k model summarized about 13k tokens of prefix for a
summary of up to 8k, so each ~100k-token request bought a few turns of
room before the next one re-summarized the previous summary. At 50% the
same request frees about 30k.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix(ai-agent): drop the workspace-S3 memory hint and state the database bound in the tooltip
The memory field warned that memory is kept in the database whenever the
workspace had no S3 storage. That setting has no bearing on where memory
goes: the instance object store decides, and nothing exposes it to the
editor. The field's tooltip now describes both memory kinds and states
the database bound unconditionally; the run log says what happened.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix(ai-agent): send the summarizer its tool history as text
The summarization request carries no tool definitions, and Bedrock's
Converse API rejects toolUse/toolResult blocks that arrive without them,
so on Bedrock every summarization of a prefix holding a tool call failed
silently until the breaker tripped. The prefix's tool calls and results
now reach the summarizer rendered as text, on the agent step and in the
AI session's compaction, which goes through the same proxy.
Also drops the TokenUsage::prompt_tokens accessor, which had become a
plain read of the normalized input_tokens, and shortens the context
window field's description.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix(ai-agent): price attachments from the provider count, bound storage in bytes, effort per pro model
Addresses two Codex rounds and a leftovers audit.
- Attachments were priced at a flat 1500 tokens in the split, so a
multi-page PDF (tens of thousands of tokens to the provider, a short
S3 path in the message list) could be kept in the tail or leave no
prefix worth summarizing. They are now priced from the provider's
count for the request that carried them, less that request's text,
with the 1500 floor where nothing was counted.
- The database storage bound measured the provider's token count, but
the 100KB cap is bytes and repetitive text packs several characters
per token. The persist pass now measures the serialized conversation.
- The summarizer forced `low` on every reasoning model, which the pro
variants reject (gpt-5-pro takes only high, gpt-5.2-pro starts at
medium); they now get no effort.
- Dropped the unused prompt_tokens accessor and its orphaned assert, an
unused PartialEq, a needlessly public lookup, and fully-qualified
Gemini calls; refreshed stale comments and the memory_id schema doc;
regenerated the flow schema artifacts.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix(ai-agent): evict a heavy attachment into the summarized prefix, not the tail
Pricing attachments from the provider count was not enough on its own: a
leading attachment is a user message, and the boundary rule pulled the
last unanswered user turn back into the kept tail to keep it with its
answer. For a heavy attachment that dragged it into the tail — or, at
the front, emptied the prefix — so it was never summarized and rode
every request. The boundary now moves forward instead, keeping that
user turn and its answer in the summarized prefix. Verified on the
running instance: a 25k-token PDF on a 30k window is summarized out on
the turn it overflows, and later turns drop from 26k to ~1.5k tokens.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix(ai-agent): keep the forward boundary move off tool results and the prefix start
The forward move that keeps an unanswered user turn out of the tail had
two edges the third Codex round found: advancing past the user could
land the boundary on a tool result (its tool_calls then summarized away,
orphaning it), and with no system prompt the summarizable prefix starts
at 0, so a trigger firing while the tail estimate fit everything indexed
below the start and panicked the task. The forward scan now skips
tool-opening boundaries, and the move is guarded above the prefix start.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix(ai-agent): drop the step temperature from the summary request
OpenAI's reasoning models (gpt-5-mini, gpt-5.1, gpt-5.2) reject
`temperature` alongside any reasoning effort but their own default, so a
step configured with a temperature made every summarization fail once
the summarizer forced a low effort — history then grew unchecked. The
internal summary call now omits the step's temperature: a structured
extraction does not need a set one, and omitting it sidesteps each
provider's temperature-versus-reasoning rules. Confirmed against the API
that low + temperature is refused on those models.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix(ai-agent): compact an oversized loaded memory before the first request
Compaction was reactive, taken only after a request the endpoint
accepted, so the fallbacks the loop learns from a rejection are known
first. But a memory loaded from an earlier run can already exceed this
run's window — the step was switched to a smaller model, or a run under
a wider one persisted more than fits — and that first request then
overflows and fails the run, with every retry reloading the same
history and failing again. A pass is now taken up front, off the
character estimate, before the first request. It uses the default
request shape; an endpoint needing a fallback may reject this one
summary, which is non-fatal, and mainstream providers need none.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix(ai-agent): under the storage bound, trigger on the max of bytes and model tokens
The storage-bound pass measured only the serialized row size, so an
attachment — a few bytes as an S3 path but nearly the whole model
context — read as tiny and the pass skipped a compaction the model
needed. It now takes the larger of the byte measure and the model's
token count, since repetitive text is few tokens but many bytes and an
attachment is the reverse; either being over must fire a pass.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix(ai-agent): drop oldest turns when a summary cannot fit the window, as the AI session does
An oversized loaded memory (a step switched to a smaller model, or an
object-store run that persisted more than a later model's window holds)
left a prefix larger than the summarizer's own window, so the summary
request overflowed and failed, the memory was untouched, and every
retry failed the same way. The AI session handles this by falling back
from summarization to dropping the oldest turns down to the target;
compaction here now does the same. When a summary cannot run — it
failed, the breaker is tripped, or nothing is worth folding — the oldest
turns are dropped until the conversation fits and opens on a user
message, keeping the newest turn. The next request then always fits.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix(ai-agent): drop whole turns only, keep the storage pass to bytes, refresh the count after a rewrite
Three edges the seventh Codex round found, all in the drop-oldest
fallback and the storage-bound measure:
- drop_oldest_to_fit dropped to any point that freed enough, which could
strand a tool result whose tool_calls went with the messages before
it. It now drops whole turns only, always landing the boundary on a
user message and never splitting the newest turn; a lone turn too big
for the window is left whole rather than broken.
- The storage-bound pass measured the whole model prompt against the
shrunk 25k window, so a large tool roster and the system prompt —
neither written to the row — tripped it on a conversation the row
easily held. It measures the serialized bytes alone now; the model's
own window is enforced by the in-loop passes and the pre-first-request
pass, so the persisted size is all this pass is for.
- A compaction rewrites the message list, so the provider's count for
the request that produced it no longer lines up. The count is now
cleared after any pass that rewrites the conversation, so a later pass
measures the estimate over the actual messages instead of a stale,
larger prompt (which could decline a summary that already fit and then
drop it). The step temperature, no longer sent to the summarizer on
any path, is dropped from the request struct.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix(ai-agent): measure only the persisted messages against the storage cap
Persistence strips the system prompt before writing the memory row, but
the storage pass was serializing every message including it, so a large
system prompt with a tiny conversation reported far over the storage
trigger, and the fallback dropped the one real turn, run after run. The
storage measure now serializes only the non-system messages, matching
what the row actually holds.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix(ai-agent): run the model-window pass before the storage-bytes pass post-loop
A turn the model answered without a tool call broke before the in-loop
compaction check, so on database-backed memory its only pass was the
storage one, which measures bytes. An attachment fills the model context
but is a few bytes in the row, so that turn never compacted and a
follow-up could overflow the model. The post-loop now runs a
model-window pass first, off the provider's count, then the
storage-bytes pass when the row is smaller than the model — both limits
enforced for a chat-shaped step, not just the one that happens to bind.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix: simplify agent compaction and preserve execution history
* fix: remove unused compaction history setting
* fix: preserve answers and recover rejected agent context
* refactor: make agent compaction transactional
* fix: skip agent summaries that cannot fit retained context
* fix: explain skipped agent context compaction
* fix: retain recent agent memory when storage compaction cannot fit
* fix: start retained agent memory at a user turn
* fix: reject unsafe agent memory truncation on storage fallback
* docs: clarify agent context window override scope
* fix: keep recent turns verbatim when compaction memory outgrows storage
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix: keep the compaction summary out of the agent's answers
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* fix: shorten the agent context window help text
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ViJyjUmidDYV2m6ifQdLeH
* chore: update ee-repo-ref to 942d4013f36edac1fc9a9addbdb02198db1c7a05
This commit updates the EE repository reference after PR #812 was merged in windmill-ee-private.
Previous ee-repo-ref: 8ca1682ce6106ba6ea96894fbe606dac64102eb6
New ee-repo-ref: 942d4013f36edac1fc9a9addbdb02198db1c7a05
Automated by sync-ee-ref workflow.
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
* fix: hide tool controls a nested AI agent cannot use
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* refactor: drop the tool navigation prop an agent tool now implies
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix: ask for a tool name on every kind of agent tool
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix: keep enabled_tools reachable on a linked nested agent tool
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* docs: name the tool kinds the header's name field actually renders
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* docs: state the tool-name rule without listing the kinds it covers
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
The identity an agent runs as lives in `value.on_behalf_of` instead of a column. Every write
of an agent resolves it server-side as a flow's is: the writer's own, unless an admin or
wm_deployers member asks to keep it, and a folder default on create. Retyping a resource into
an agent resolves its value the same way. Export leaves it out; the run endpoint reads it and
drops it from the step's inputs.
The CLI follows the app model: a pushed agent never takes its identity from the tracked file,
an unchanged agent compares equal to the deployed one, and an admin or deployer push claims
the deployed identity back. The owner-change pre-check lists agents.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix: support aiagent steps in test_run_step
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix: offer the agent's tools as a picker in the step run form
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix: run a blank tool list as no tools when the step form is bypassed
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* feat: chat with a saved agent from the agent editor
* fix: keep agent chats apart from a same-path flow's conversations
* fix: point an agent editor chat's model gap at the agent, not a step
* fix: match the memory gate's icon to the chat's empty state
* feat: edit variables, resources and triggers in their own session tab
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: take a trigger's flow kind from its config and name the written trigger
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* refactor: one operating-workspace context for editors acting on a session's workspace
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: reload page item tabs only in sessions acting on the tool's workspace
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: resolve open in workspace for every preview tab kind in one place
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: guard every component under a session editor against the navigation workspace
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: show a page item tab whose item is gone instead of mounting its editor
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: follow a saved page item in the tab's own workspace and restore in-frame rows
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat: close a page item tab from its editor header
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: judge trigger permissions by the user acting in the session workspace
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: judge every session-editor permission by the user acting in that workspace
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: keep session permissions reactive to the acting role and restore tabs as last seen
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: default Path's owner controls to the user acting in its workspace
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
* feat: render an AI agent result as its answer, not as raw JSON
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: sanitize agent markdown through the shared plugin chain
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* refactor: fold agent stream events incrementally per poll
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: separate the agent meta line from the result toggle group
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat: add a transcript view of an agent run's conversation
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* refactor: retire AIAgentLogViewer in favour of the transcript
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat: show the partial transcript a max-iterations failure carries
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: move the agent meta line and system prompt below the conversation
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* refactor: show an agent run as what it did, not as a conversation
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* refactor: name the agent run breakdown a trace
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(ai-agent): label the save-as-agent form fields per the guidelines
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(ai-agent): reuse the resource form's path and description fields
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(ai-agent): keep the action tags on a max-iterations failure
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(ai-agent): keep offline replay inert and the streamed answer to one turn
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(ai-agent): reset the streamed answer on providers that skip tool_call
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: carry the event type narrowing through the stream parser
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: survive a malformed message rather than take the viewer down
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* refactor: coerce agent messages once at the parse boundary
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat: show an agent run as one scroll ending in its output
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: keep every streamed turn instead of dropping the narration
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: share the chat divider and drop the unsafe run auto-scroll
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: give the labelled divider a border colour and the standard pretty icon
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: pad the agent run below its badges as well as above
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat: follow a streaming run's pane without moving the page
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* refactor: share the chat's stick-to-bottom mechanics with the agent run
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: keep the answer's citations and end a turn's reasoning with the turn
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* refactor: read the agent stream through the windmill-chat sdk parser
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: show an agent run's thinking instead of falling back to raw json
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: stop a stream the fold cannot use from claiming the run pane
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: identify an agent run by more than the job id the replay withholds
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* refactor: drop the tests and comment lines that were not earning their place
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: stop a streamed turn's text shifting when a tool call closes it
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat: flow chat job-backed detail, smooth streaming and answer chrome
* chore: document setFlowPath, drop unused chatIdentity, tighten comments
* fix: read a nested agent tool's call from its own job
* fix: show only the model's arguments on a tool card read from its job
* feat: add attachments to the chat sdk message type
* refactor: read a flow chat message's files from the message, not its run
* fix: keep every job-backed answer when reads finish out of order
* refactor: build flow chat tool cards from the conversation row alone
* feat: keep the model picker's current choice when a flow chat retry replays its run
* fix: export ChatAttachment from the chat sdk entry point
* fix: drop a conversation list for the flow path before setFlowPath
* fix: return the current listing, not old-path rows, after setFlowPath
* fix: treat a listing stale on kind or path as one stale listing
* revert: drop setFlowPath and rebuild the chat when the flow path changes
* fix: refuse a flow chat retry once any turn ran while it read the run
* docs: say where a display message's createdAt comes from
* style: drop the rule between New chat and the conversation list
* feat: attach files to a flow chat message
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: store chat uploads under windmill_uploads and withdraw refused sends cleanly
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: refuse extra files for a single-file input and keep attachments on retry
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: clean up partial upload batches, withdraw a stopped send once, free retry payloads
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: list a chat conversation only once its run starts and require files where the flow does
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat: carry uploaded attachments on the pending chat user message
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: route rich-composer file paste through the attachment lanes and tighten comments
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: keep a stopped turn's files for retry and let an explicit media type win
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: refuse chat attachments sent without text and shorten comments
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: resolve the attachments input from real flow input reads, ignoring loop iteration
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* refactor: read flow input references through one parser for the model and attachments controls
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: withdraw an attachment send stopped after its uploads answered
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: discard uploads when a send is stopped as its attachments are announced
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs: keep uploadAttachments' doc comment on uploadAttachments
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* refactor: never delete chat uploads from workspace storage
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* test: pin that a failed upload aborts the rest of its batch
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
* feat: split ai agent memory into agent policy, run memory id and step history
* fix: scope string memory ids to workspace and flow, keep nested tool history inputs
* chore: update sqlx cache for the flow context query
* docs: describe memory id scoping as collision-free rather than isolated
* chore: regenerate openflow json after merging main
* fix: offer no memory id for legacy manual memory, document linked history inputs
* fix: seed provided messages from legacy manual memory and hide its note once set
* fix: bypass memory when a provided messages expression evaluates to null
* fix: require a user message when provided messages are empty
* chore: keep the empty messages comment within the line width
* docs: name the history inputs wherever linked steps list their flow-local inputs
* docs: keep the memory storage path on one line
* feat: managed memory with an inherited or custom memory id per step
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix: list a custom memory id in the test run form and name where an inherited one comes from
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix: keep memory id out of the add-field menu and drop the memory id telemetry
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix: keep legacy auto memory without an id working after an untouched redeploy
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix: rename step messages to previous_messages and address review
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* style: rewrap comments and docs lines lengthened by the previous_messages rename
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* refactor: read agent memory as either a legacy shape or the current one
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix: name the memory setting in ignored-input notes and keep conversions honest
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix: keep a legacy memory count unset on open and read a cleared count as off
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* fix: address review on cleared test history and zero-count memory
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* fix: drop flow-local keys from a linked agent resource before interpolating it
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* fix: keep a linked resource's own inputs as fallbacks and note ignored history on image runs
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* fix: restore the linked agent draft tests and log ignored history on every image run
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* fix: resolve the one-of variant from the value when the selected one leaves the list
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* fix: treat zero-count managed memory as off when enabling chat mode and shorten comments
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* fix: stop requiring user_message in the openflow agent contract when previous messages are the prompt
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
* feat: mark test flow conversations apart from deployed ones and allow renaming a chat
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* fix: keep the conversation kind across refreshes and reject NUL titles
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* fix: ignore conversation lists for a kind no longer selected
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: start a fresh conversation listing when the kind changes on a later page
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: refuse sending into a conversation of the other kind
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: refuse cross-kind conversation continuations on the server
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: keep the conversation filter unavailable while an answer runs
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
* refactor: render the session chat model menu from a shared ChatModelSettings config
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* feat: pick the flow chat's model and thinking from the provider fields the flow exposes
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* fix: name only the thinking level the flow run will send on the model button
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: let the flow chat take a typed model id and keep a shared thinking input editable
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: promote a flow input to the model button only where its control can edit it
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: drop any reasoning token the chosen model rejects before a flow chat run
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
* feat: keep flow inputs and seed the agent when chat mode is enabled
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* fix: leave a linked agent's memory and streaming to the agent when enabling chat mode
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
* feat: list flows that link a saved agent and flag broken agent links
* feat: rename saved agents from the agent editor and repoint the flow
* fix: show an unreadable linked agent as not accessible, not missing
* fix: address review nits on agent rename and missing-agent state
* fix: open content search above modals and keep Escape for it
* fix: register content search on the opener's overlay stack
* docs: scope the global search z-index comment to the bases it clears
* refactor: show linked agents' rename warning as for scripts and flows
* fix: keep the failed-lookup rename warning to resources
* refactor: run the flow chat UI on the windmill-chat sdk
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* fix: structural answer check, poll option and latest run in the chat sdk
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* fix: count jobless tool rows and the loaded license in the flow chat
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
* feat: dynamic ai agent toolsets, and memory as a step input
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: address review round 1 on dynamic ai agent toolsets
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* refactor: tag enabled_tools and drop the memory step input
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: let an mcp server entry be named by the path the roster shows
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: keep $res: out of the tool names the enabled tools picker offers
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: name an mcp server by its bare path on the one side that can hold it
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: count the enabled tool names that matched nothing instead of logging them
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* refactor: narrow an agent's roster in one pass, by whole entries
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* test: pin that an mcp summary is rejected against a name that is not
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* chore: regenerate the copilot flow schema after the merge
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs: shorten the enabled tools list hint
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* refactor: take enabled_tools back to a plain list of tool names
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs: keep the enabled tools add-menu hint describing the unset field
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: name a websearch tool that carries no summary of its own
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix: reserve the name web search is enabled by so no tool can share it
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* refactor: spell the reserved web search name with a hyphen
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* refactor: reserve __wm_web_search as the name web search is enabled by
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* chore: advance ee-repo-ref past the git sync ci check work
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* docs: shorten the enabled tools description the run form shows
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* chore: update ee-repo-ref to e4c1b794d6c5e6e390987341b2840587bbb40348
This commit updates the EE repository reference after PR #785 was merged in windmill-ee-private.
Previous ee-repo-ref: af668462f0f06b02a5f4e0c22e6156858487a518
New ee-repo-ref: e4c1b794d6c5e6e390987341b2840587bbb40348
Automated by sync-ee-ref workflow.
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Ruben Fiszel <ruben@windmill.dev>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
* feat(frontend): group the AI agent step form and edit saved agents in a modal
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* feat: edit a saved AI agent through its own resource draft
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* refactor: drop the agent fork-for-edit session now that edits live in a draft
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* feat: edit ai_agent resources from the resources page with the agent editor
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix: send a standalone agent's brain from the module when testing a step
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix: keep the agent draft faithful to the resource it deploys to
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* chore: add the sqlx cache entry for the eval subject rename
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* refactor: share the module insert between the graph and the agent editor
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* feat(frontend): open evals inside the agent editor, actions in its header
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* feat(frontend): add tools from the agent editor and lighten its test pane
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(frontend): open an ai_agent deep link in the agent editor
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(frontend): drop the failed result badge on a step that never ran
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* feat(frontend): head the agent editor's levels with a back control
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* feat(frontend): drop connect and fill inputs from the agent editor
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* feat(frontend): lighten the agent editor's run panel
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(frontend): stop a nested agent tool's config reading as AI-filled
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* feat(frontend): offer only AI or static on an agent tool's inputs
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* feat(frontend): give a saved agent's tool editor a static-only surface
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* feat(frontend): open an agent tool in a drawer beside the agent
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* feat(frontend): hide unset agent config in the run form
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* refactor(frontend): share the input forms' pickers and s3 lookup
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* chore(frontend): drop a dead agent-editor export and fix two stale comments
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(frontend): reach an ai_agent's resource-level settings and copilot
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(frontend): open an ai_agent's resource view as JSON, not the generic form
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(frontend): address review findings on the agent editor's draft and streaming
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(frontend): close the agent editor on a version restore, as the resource editor does
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(frontend): stop the provider picker auto-writing a kind, and clear review nits
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* refactor(frontend): drop the fork-for-edit leftovers from the agent card
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(frontend): mount the agent editor in the dev flow editor and guard the deep-link race
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(frontend): deploy the agent config that was submitted, and refuse one no run could use
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* refactor(frontend): build the agent editor's rows from the design-system button
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(frontend): keep a draft-only agent's draft, and let a blank MCP summary deploy
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(frontend): guard read-only agents, incomplete MCP tools and duplicate editor mounts
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix: read-only agent editor, linked-card refresh, atomic eval rename
* fix: eval rename needs the privileged pool, per-workspace write access
* fix(frontend): drop the agent editor target when its mount goes away
* refactor: drop the agent rename work from this PR, unban the bindable defaults
* fix(frontend): refuse a renaming deploy and drop the copilot from static-only fields
* fix(frontend): mirror the worker's streaming rule and scope agent writes to their target
* fix(frontend): read runtime streaming as off and reset the drawer's json view
* fix(frontend): read an unsettled output_type as non-streaming too
* fix(frontend): let the showing modal claim an agent opened from inside it
* fix(frontend): keep in-flight edits, tool replacements and every linked step in sync
* fix(frontend): keep attachments in the run form and bind the agent ref to its tools
* fix(frontend): preview the agent as authored and re-evaluate step args on run
* fix(frontend): scope agent-editor ownership to the flow's workspace
* fix(frontend): drop the tool drill-in where there is no graph to select on
* fix(frontend): require a provider kind and keep one resource editor open at a time
* fix(frontend): keep legacy nulls, static-only text literal, and the handover anchor
* test(worker): pin the agent streaming default
* fix(frontend): let an AI-fillable input be switched to static
* fix(frontend): report agent editor background failures instead of floating them
* fix(frontend): keep the version pane's path alive while the editor closes
* fix(frontend): clear the anchor-keep flag at the start of each drawer session
* fix(frontend): preview the agent without its synthetic path, refresh the baseline on external writes
* refactor(frontend): drop the unverifiable baseline refresh, state the synthetic-path rule
* fix(frontend): keep the synthetic path out of agent tool test runs too
* refactor(frontend): host the agent editor under the agent's own path
* fix(frontend): mark an agent editor's host explicitly instead of inferring it from the path
* fix(frontend): discard linked-agent responses from before a deploy
* fix(frontend): keep a flow mount from claiming an agent editor's nested target
* feat(frontend): keep an agent used as a tool inside the agent being edited
* fix(frontend): reserve the agent editor's root module id
* docs(frontend): record why the agent editor previews under the agent's path
* fix(frontend): refuse to open or deploy a resource that is not an agent
* docs(frontend): put the scope-migration comment on the function it describes
* fix(frontend): refuse an agent path whose resource type is not proven
* fix(frontend): recheck the resource type before deploying, and keep expressions off static-only inputs
* fix(frontend): lazy-load the agent editor and slide its levels like the evals pane
* refactor: drop unreachable non-list tools check from agent deploy
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(frontend): clear text-only agent fields on image output, reserve the root id
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(frontend): keep the agent editor usable for a non-list tools value
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(frontend): stop the parked eval run list from taking arrow keys
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(frontend): report a non-list tools value on deploy instead of throwing
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(frontend): keep temperature editable for image output
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(frontend): skip non-object tool entries when rendering an agent
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(frontend): guard tool entry reads instead of copying the tool array
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* fix(frontend): key tool rows by position so duplicate ids render
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>