fix(coding-agent): resolved third review pass on inspect_image vision mode
- read now treats an xd://-mounted inspect_image as available (top-level predicate OR mounted device gated by the effective mode), so default xdev sessions with a text-only model keep metadata-guidance reads instead of inlining images the provider boundary would scrub - advisor tool session stops inheriting the primary's isToolActive and xdevRegistry: advisors cannot execute xd:// devices, so their reads inline images again - setModelWithProviderSessionReset is now async and awaited at every callsite, so retry-fallback model switches cannot race the inspect_image tool-slate reconcile - regression tests for both xd:// availability directions
This commit is contained in:
@@ -874,7 +874,7 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
||||
1,
|
||||
Math.min(session.settings.get("read.defaultLimit") ?? DEFAULT_MAX_LINES, DEFAULT_MAX_LINES),
|
||||
);
|
||||
this.#inspectImageActive = session.isToolActive?.("inspect_image") ?? isInspectImageToolActive(session);
|
||||
this.#inspectImageActive = this.#resolveInspectImageAvailability();
|
||||
this.description = this.#renderDescription();
|
||||
}
|
||||
|
||||
@@ -894,21 +894,33 @@ export class ReadTool implements AgentTool<typeof readSchema, ReadToolDetails> {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the agent can actually reach `inspect_image` right now: exposed
|
||||
* top-level, or mounted as an `xd://` device while the effective mode wants
|
||||
* it (mounted devices stay executable via `write xd://inspect_image`, so a
|
||||
* metadata-only read remains actionable). Sessions with neither
|
||||
* availability signal (tests, embedded use) fall back to the mode
|
||||
* computation alone. Restricted slates (subagents without the tool and
|
||||
* without xdev) resolve to unavailable, so those sessions get inline image
|
||||
* blocks instead of guidance pointing at an absent tool.
|
||||
*/
|
||||
#resolveInspectImageAvailability(): boolean {
|
||||
const topLevel = this.session.isToolActive?.("inspect_image");
|
||||
const registry = this.session.xdevRegistry;
|
||||
if (topLevel === undefined && registry === undefined) return isInspectImageToolActive(this.session);
|
||||
if (topLevel === true) return true;
|
||||
return registry?.get("inspect_image") !== undefined && isInspectImageToolActive(this.session);
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-evaluate the effective inspect_image state; it can flip when the model
|
||||
* or the `/vision` override changes after this tool was constructed. Keeps
|
||||
* the behavior branch and the advertised description in lockstep. Called
|
||||
* per image read and by tool reconciliation before prompt rebuilds.
|
||||
*
|
||||
* Actual tool availability wins over the mode computation: restricted
|
||||
* sessions (explicit tool slates without `inspect_image`, e.g. subagents)
|
||||
* must never see metadata-only reads pointing at an absent tool. Sessions
|
||||
* without an `isToolActive` predicate (tests, embedded use) fall back to
|
||||
* the mode check.
|
||||
* per image read and by tool reconciliation before prompt rebuilds (which
|
||||
* passes the post-change availability as `availableOverride`).
|
||||
*/
|
||||
syncInspectImageState(availableOverride?: boolean): boolean {
|
||||
const active =
|
||||
availableOverride ?? this.session.isToolActive?.("inspect_image") ?? isInspectImageToolActive(this.session);
|
||||
const active = availableOverride ?? this.#resolveInspectImageAvailability();
|
||||
if (active !== this.#inspectImageActive) {
|
||||
this.#inspectImageActive = active;
|
||||
this.description = this.#renderDescription();
|
||||
|
||||
Reference in New Issue
Block a user