Configure CUA image context and response threading#53
Conversation
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
Autofix Details
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Exported replay limit type lacks TSDoc
- Added TSDoc to ToolResultImageReplayLimit clarifying its non-negative integer cap semantics and false bypass behavior.
Or push these changes by commenting:
@cursor push ae5e864071
Preview (ae5e864071)
diff --git a/packages/agent/src/agent.ts b/packages/agent/src/agent.ts
--- a/packages/agent/src/agent.ts
+++ b/packages/agent/src/agent.ts
@@ -40,6 +40,11 @@
const DEFAULT_TOOL_RESULT_IMAGE_REPLAY_LIMIT = 4;
const OMITTED_TOOL_RESULT_IMAGES = "[stale tool-result images omitted]";
+/**
+ * Maximum number of tool-result image blocks replayed from local history.
+ * Use a non-negative integer cap (`0` omits all images) or `false` to skip
+ * projection and keep the original message history unchanged.
+ */
export type ToolResultImageReplayLimit = number | false;
function resolveToolResultImageReplayLimit(limit: ToolResultImageReplayLimit | undefined): ToolResultImageReplayLimit {You can send follow-ups to the cloud agent here.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
Autofix Details
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Threading disable skips stream
- Updated
withoutResponseThreadingto injectdisableResponseThreading: trueforstreamandcompletein addition tostreamSimple/completeSimple, so all harness model entry points stay full-context when threading is disabled.
- Updated
Or push these changes by commenting:
@cursor push 103d4b0533
Preview (103d4b0533)
diff --git a/packages/agent/src/agent.ts b/packages/agent/src/agent.ts
--- a/packages/agent/src/agent.ts
+++ b/packages/agent/src/agent.ts
@@ -351,8 +351,12 @@
}
function withoutResponseThreading(models: Models): Models {
+ const withResponseThreadingDisabled = (options: CuaSimpleStreamOptions | undefined): CuaSimpleStreamOptions => ({
+ ...options,
+ disableResponseThreading: true,
+ });
const streamSimple: Models["streamSimple"] = (model, context, options) =>
- models.streamSimple(model, context, { ...options, disableResponseThreading: true } as CuaSimpleStreamOptions);
+ models.streamSimple(model, context, withResponseThreadingDisabled(options as CuaSimpleStreamOptions | undefined));
return {
getProviders: () => models.getProviders(),
getProvider: (id) => models.getProvider(id),
@@ -360,8 +364,9 @@
getModel: (provider, id) => models.getModel(provider, id),
refresh: (provider) => models.refresh(provider),
getAuth: (model) => models.getAuth(model),
- stream: (model, context, options) => models.stream(model, context, options),
- complete: (model, context, options) => models.complete(model, context, options),
+ stream: (model, context, options) => models.stream(model, context, withResponseThreadingDisabled(options as CuaSimpleStreamOptions | undefined)),
+ complete: (model, context, options) =>
+ models.complete(model, context, withResponseThreadingDisabled(options as CuaSimpleStreamOptions | undefined)),
streamSimple,
completeSimple: (model, context, options) => streamSimple(model, context, options).result(),
};You can send follow-ups to the cloud agent here.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Harness completeSimple skips image cap
- Updated
withContextManagementsocompleteSimpledelegates to the cappedstreamSimplepath, and adjusted the harness test expectation to verify the image cap is applied.
- Updated
Or push these changes by commenting:
@cursor push 9c7c960e3b
Preview (9c7c960e3b)
diff --git a/packages/agent/src/agent.ts b/packages/agent/src/agent.ts
--- a/packages/agent/src/agent.ts
+++ b/packages/agent/src/agent.ts
@@ -380,7 +380,7 @@
withResponseThreading(options, responseThreading),
);
const completeSimple: Models["completeSimple"] = (model, context, options) =>
- models.completeSimple(model, context, withResponseThreading(options, responseThreading));
+ streamSimple(model, context, options).result();
return {
getProviders: () => models.getProviders(),
getProvider: (id) => models.getProvider(id),
diff --git a/packages/agent/test/agent.test.ts b/packages/agent/test/agent.test.ts
--- a/packages/agent/test/agent.test.ts
+++ b/packages/agent/test/agent.test.ts
@@ -786,7 +786,7 @@
await harness.models.completeSimple(model, context);
expect(streamOptions?.disableResponseThreading).toBe(expected);
- expect(providerImageCount).toBe(5);
+ expect(providerImageCount).toBe(4);
});
it("applies image projection after user context hooks", async () => {You can send follow-ups to the cloud agent here.
Reviewed by Cursor Bugbot for commit a2bf729. Configure here.


Summary
toolResultImageReplayLimitandresponseThreadingonCuaAgent,CuaAgentHarness, and the CLI harness buildercontexthook result, so user context handlers compose with the built-in limit instead of replacing itModels.stream,complete,streamSimple, andcompleteSimpletransformContext, harnesscontexthooks, session entry transforms, and persistentcompact()summariesTesting
npm run typecheckenv -u GOOGLE_API_KEY -u GEMINI_API_KEY npm test --workspace @onkernel/cua-ai(142 passed)npm test --workspace @onkernel/cua-agent -- --exclude '**/*.live.test.ts'(121 passed)npm test --workspace @onkernel/cua-cli(82 passed, 5 skipped)git diff --checkNote
Medium Risk
Changes what every provider request sends (images and OpenAI/Tzafon threading), which can affect model behavior and token usage; defaults aim to preserve prior threading-on behavior while capping images.
Overview
Adds request-time context controls so long browser runs do not ship unbounded screenshot history to providers, while agent state and sessions keep full images.
toolResultImageReplayLimit(default 4) trims older tool-result image blocks per provider call, inserts a single[stale tool-result images omitted]marker where needed, and leaves text/metadata/order intact.CuaAgentapplies it after any callertransformContext;CuaAgentHarnessapplies it at theModelsboundary after harnesscontexthooks so custom handlers compose with the built-in cap. Setfalseto disable projection.responseThreading(defaulttrue) toggles OpenAI/Tzafonprevious_response_idchaining vs full-context requests viadisableResponseThreading. TheCUA_DISABLE_RESPONSE_THREADINGenv toggle is removed in favor of this constructor/CLI option.Options are exposed on
CuaAgent,CuaAgentHarness,buildCuaHarness, and documented in the agent README, with broad test coverage for limits, threading, batch/multi-image cases, and validation.Reviewed by Cursor Bugbot for commit 51eb722. Bugbot is set up for automated code reviews on this repo. Configure here.