Skip to content

Upgrade pi to 0.83.0 and adopt context-first harness tools - #72

Merged
rgarcia merged 8 commits into
mainfrom
hypeship/upgrade-pi-083
Aug 4, 2026
Merged

Upgrade pi to 0.83.0 and adopt context-first harness tools#72
rgarcia merged 8 commits into
mainfrom
hypeship/upgrade-pi-083

Conversation

@rgarcia

@rgarcia rgarcia commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Upgrades the whole pi stack to exact 0.83.0 (@earendil-works/pi-ai, pi-agent-core, pi-coding-agent, pi-tui) with one deduplicated instance of each, and adopts pi 0.83's context-first harness API as a breaking release: @onkernel/cua-ai 0.10.0, @onkernel/cua-agent 0.10.0, @onkernel/cua-cli 0.9.0 (0.8.0 shipped from main with queued-turn steering while this PR was open).

Harness redesign (@onkernel/cua-agent)

  • CuaAgentHarness and CuaAgentHarnessOptions are now TContext-firstCuaAgentHarness<TContext, TSkill, TPromptTemplate> — mirroring pi's AgentHarness generic order and semantics. The supplied toolContext is forwarded to pi untouched.
  • Executable harness tools are pi AgentHarnessTool<TContext> via the new CuaHarnessTool<TContext> union (a CUA spec or an AgentHarnessTool). CuaAgent stays on the ordinary pi AgentTool (CuaAgentTool); the two tool APIs are no longer conflated. CuaToolManager now materializes both views from one compiled catalog.
  • Removed CuaAgentHarnessOptions.env, CuaAgentHarness.env, and CuaSystemPromptCallback — no aliases. Execution environments travel through the tool context; systemPrompt is pi's AgentHarnessSystemPrompt.
  • CuaAgentHarnessOptions.retry omits pi's new harness retry?: RetryPolicy (compaction/branch-summary) so it keeps meaning CUA's provider retry policy, unchanged.
  • streamFn stays optional on CuaAgentOptions (CUA supplies its default stream) even though pi 0.83 makes AgentOptions.streamFn required.
  • Published declarations target pi's TypeBox 1.3 as-is.

CLI (@onkernel/cua-cli)

  • Coding tools moved from pi-coding-agent createCodingTools(cwd) to pi-agent-core createReadTool/createBashTool/createEditTool/createWriteTool (read/bash/edit/write order preserved), with toolContext: { env: new NodeExecutionEnv({ cwd }) }.
  • Kimi K3 now follows pi's catalog metadata with no override: low/high/max map through thinkingLevelMap, and the CLI default (--thinking unset → low) sends reasoning_effort: "low" to Moonshot and reasoning: { effort: "low" } through OpenRouter. New payload regression tests pin both.

Models (@onkernel/cua-ai)

  • Removed the local claude-opus-5, gemini-3.6-flash, and gemini-3.5-flash-lite overrides — pi 0.83's registry carries all three with the same metadata. Overrides remain only for the CUA-only providers pi does not ship (Meta, Tzafon, Yutori).

Tzafon native action-loop guard (@onkernel/cua-ai)

  • Tzafon's native continuation protocol requires every computer_call_output to carry an image. CUA does not synthesize post-action screenshots, so native non-screenshot actions now fail before browser execution instead of entering an unsupported text-only loop. Explicit screenshot and terminal answer actions remain supported.
  • Explicit Tzafon screenshot results are retained in model context even beyond toolResultImageReplayLimit, since pruning them would make valid history impossible to replay through that protocol. Other tool-result images remain bounded.

Tests

  • npm run typecheck (clean build): pass.
  • @onkernel/cua-ai: 114 passed. @onkernel/cua-agent: 291 passed, 19 skipped (live tests self-skip without KERNEL_API_KEY). @onkernel/cua-cli: 141 passed, 14 skipped (ptywright native binding not built locally).
  • New: harness-context.test.ts proves a custom harness tool receives the exact supplied context object and drives pi's native read/write/edit/bash tools through CUA against a real temp directory; published-declarations.test.ts compiles a downstream consumer against the packaged dist/ declarations with skipLibCheck: false; kimi-reasoning-payload.test.ts pins the default-low payloads; Tzafon provider tests pin the native non-screenshot rejection before browser execution.
  • Built CLI smoke-tested (cua models, cua --help) without secrets.
  • npm ls: single 0.83.0 of each pi package, single typebox 1.3.7.
  • npm audit: 3 remaining advisories (brace-expansion, undici via pi-coding-agent, and a moderate) are pre-existing on main and pinned by upstream dependency ranges; not changed by this PR.
  • Pre-existing, unrelated: packages/ptywright's own test suite fails on main with extensionless ESM imports (ERR_MODULE_NOT_FOUND for dist/index); this PR does not touch ptywright. Latent type errors in browser-wait.test.ts / cli-executor.test.ts also predate this change (test files are outside every tsconfig project).

Note

High Risk
Breaking public harness and CLI APIs plus a major pi/TypeBox bump affect all consumers; Tzafon and image-replay behavior changes are easy to miss in integration testing.

Overview
Bumps the monorepo to pi 0.83.0 (pi-ai, pi-agent-core, pi-coding-agent, pi-tui) and ships breaking 0.10.0 agent/ai and 0.9.0 CLI releases.

CuaAgentHarness is now context-first: generics are CuaAgentHarness<TContext, …>, harness tools are CuaHarnessTool / pi AgentHarnessTool with toolContext forwarded on each call, and env on the harness is removed (execution env goes through toolContext, e.g. NodeExecutionEnv for read/bash/edit/write). CuaAgent keeps context-free CuaAgentTool; CuaToolManager exposes both agent and harness tool views from one catalog.

CLI swaps createCodingTools for pi-agent-core read/bash/edit/write tools and wires toolContext: { env }. Kimi K3 default thinking maps to reasoning_effort: low per pi catalog metadata.

@onkernel/cua-ai drops local overrides for Opus 5 and Gemini models now in pi’s registry. Tzafon rejects native non-screenshot computer actions and text-only native tool results because continuation requires images CUA does not auto-capture. Agent exempts Tzafon native screenshot tool results from toolResultImageReplayLimit trimming.

New tests cover harness tool context, published declarations with skipLibCheck: false, Kimi payloads, and Tzafon guards; docs note pi 0.83.0 for dynamic setTools() behavior.

Reviewed by Cursor Bugbot for commit e922447. Bugbot is set up for automated code reviews on this repo. Configure here.

rgarcia added 2 commits August 3, 2026 21:45
- Upgrade @earendil-works/pi-ai, pi-agent-core, pi-coding-agent, and
  pi-tui to exact 0.83.0 with one deduplicated instance of each.
- Redesign CuaAgentHarness on pi's TContext-first AgentHarness generics:
  CuaAgentHarness<TContext, TSkill, TPromptTemplate> accepts and forwards
  toolContext directly, and executable harness tools are pi
  AgentHarnessTool<TContext> via the new CuaHarnessTool<TContext> union.
  CuaAgent stays on the ordinary AgentTool (CuaAgentTool).
- Remove CuaAgentHarnessOptions.env, CuaAgentHarness.env, and
  CuaSystemPromptCallback with no aliases; execution environments now
  travel through the tool context.
- Move CLI coding tools from pi-coding-agent createCodingTools(cwd) to
  pi-agent-core createReadTool/createBashTool/createEditTool/
  createWriteTool (order preserved), supplying
  toolContext: { env: new NodeExecutionEnv({ cwd }) }.
- Adopt pi's Kimi K3 low/high/max reasoning-effort metadata and request
  behavior with no override; pin the metadata and add payload regression
  coverage for the CLI default low level on Moonshot and OpenRouter.
- Drop the local claude-opus-5 and gemini-3.6-flash/3.5-flash-lite
  overrides now carried by pi's registry; keep the CUA-only Meta, Tzafon,
  and Yutori models.
- Add a downstream published-declaration compile test (skipLibCheck:
  false) and context-delivery tests proving custom harness tools receive
  the exact supplied context, exercising pi's native read/bash/edit/
  write tools through CUA.
- Release as @onkernel/cua-ai 0.10.0, @onkernel/cua-agent 0.10.0, and
  @onkernel/cua-cli 0.8.0.
Comment thread package-lock.json
Tzafon's Responses API rejects a computer_call_output whose output
carries no image (400: empty image slot). After a non-screenshot action
the tool result was text-only, so the follow-up request after any click
or keypress failed and the turn ended in an API error.

The Tzafon native computer spec now declares a postActionScreenshot
execution policy, and CuaExecutionResources attaches a best-effort
post-execution screenshot when an action batch produced no image read,
on success and failure alike. A failed capture never masks the action
outcome. Canonical and other provider-native tools are unchanged.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Autofix Details

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Missing TSDoc on exported helper
    • Added a TSDoc block to the exported mapThinkingLevel helper documenting purpose, defaulting behavior, and invalid-input error contract.

Create PR

Or push these changes by commenting:

@cursor push 21209a2a93
Preview (21209a2a93)
diff --git a/packages/cli/src/cli-harness.ts b/packages/cli/src/cli-harness.ts
--- a/packages/cli/src/cli-harness.ts
+++ b/packages/cli/src/cli-harness.ts
@@ -487,6 +487,12 @@
 	return value && value.length > 0 ? value : undefined;
 }
 
+/**
+ * Normalize CLI `--thinking` values to canonical harness thinking levels.
+ *
+ * Defaults to `"low"` when the flag is unset or empty, and throws when the
+ * input does not match a supported level.
+ */
 export function mapThinkingLevel(raw: string | undefined): "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max" {
 	const v = (raw ?? "low").trim().toLowerCase();
 	switch (v) {

You can send follow-ups to the cloud agent here.

Comment thread packages/cli/src/cli-harness.ts
Add the missing TSDoc on the newly exported mapThinkingLevel and record
the postActionScreenshot execution policy in both 0.10.0 changelogs.
@rgarcia rgarcia closed this Aug 4, 2026
@rgarcia rgarcia reopened this Aug 4, 2026
rgarcia added 3 commits August 4, 2026 00:08
cua-cli 0.8.0 shipped from main with queued-turn steering, so the pi
0.83 CLI changes here move to a new 0.9.0 entry; the changelog conflict
resolves to both entries and packages/cli bumps to 0.9.0.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: Tzafon image guard blocks continuations
    • Native Tzafon tool-result replay now emits a text-backed computer_screenshot.error payload when no image is present instead of throwing, so valid text-only continuations no longer hard-fail.

Create PR

Or push these changes by commenting:

@cursor push 62940dda82
Preview (62940dda82)
diff --git a/packages/ai/src/providers/tzafon/provider.ts b/packages/ai/src/providers/tzafon/provider.ts
--- a/packages/ai/src/providers/tzafon/provider.ts
+++ b/packages/ai/src/providers/tzafon/provider.ts
@@ -344,15 +344,12 @@
 				.trim();
 			const image = [...message.content].reverse().find((part): part is ImageContent => part.type === "image");
 			if (nativeComputerName && message.toolName === nativeComputerName) {
-				if (!image) {
-					throw new Error(
-						"Tzafon native computer action loops require image tool results; text-only results are unsupported because CUA does not capture post-action screenshots automatically.",
-					);
-				}
 				items.push({
 					type: "computer_call_output",
 					call_id: message.toolCallId,
-					output: { type: "computer_screenshot", image_url: `data:${image.mimeType};base64,${image.data}` },
+					output: image
+						? { type: "computer_screenshot", image_url: `data:${image.mimeType};base64,${image.data}` }
+						: { type: "computer_screenshot", error: message.isError ? text || "tool execution failed" : text || "no screenshot" },
 				});
 				continue;
 			}

diff --git a/packages/ai/test/tzafon-provider.test.ts b/packages/ai/test/tzafon-provider.test.ts
--- a/packages/ai/test/tzafon-provider.test.ts
+++ b/packages/ai/test/tzafon-provider.test.ts
@@ -99,8 +99,8 @@
 		expect(toolCalls(message.content)).toEqual([]);
 	});
 
-	it("rejects text-only native computer results before sending a request", () => {
-		expect(() => tzafon.buildTzafonRequestInput(model, {
+	it("serializes text-only native computer results as computer_screenshot errors", () => {
+		const payload = tzafon.buildTzafonRequestInput(model, {
 			messages: [
 				{
 					role: "assistant",
@@ -125,7 +125,19 @@
 		}, {
 			disableResponseThreading: true,
 			cuaIncomingToolPlan: { tzafonComputerName: "computer", yutoriNames: {}, googleNames: {}, googleExcludedNames: [], nativeToolNames: ["computer"] },
-		})).toThrow("text-only results are unsupported");
+		});
+
+		expect(payload.input).toEqual(expect.arrayContaining([
+			expect.objectContaining({ type: "computer_call", call_id: "call_click" }),
+			expect.objectContaining({
+				type: "computer_call_output",
+				call_id: "call_click",
+				output: {
+					type: "computer_screenshot",
+					error: "Actions executed successfully.",
+				},
+			}),
+		]));
 	});
 
 	it("degrades malformed function-call arguments to empty args instead of failing the turn", async () => {

You can send follow-ups to the cloud agent here.

Reviewed by Cursor Bugbot for commit f588ba4. Configure here.

Comment thread packages/ai/src/providers/tzafon/provider.ts
@rgarcia
rgarcia merged commit 1c5caef into main Aug 4, 2026
6 checks passed
@rgarcia
rgarcia deleted the hypeship/upgrade-pi-083 branch August 4, 2026 02:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant