fix: keep pi-ai tool types for published sdk

This commit is contained in:
Peter Steinberger
2026-01-01 17:01:56 +00:00
parent 3eb3f38adf
commit 956db9c182
8 changed files with 18 additions and 21 deletions

View File

@@ -86,7 +86,7 @@
- macOS menu: top status line now shows pending node pairing approvals (incl. repairs). - macOS menu: top status line now shows pending node pairing approvals (incl. repairs).
- CLI: avoid spurious gateway close errors after successful request/response cycles. - CLI: avoid spurious gateway close errors after successful request/response cycles.
- Agent runtime: clamp tool-result images to the 5MB Anthropic limit to avoid hard request rejections. - Agent runtime: clamp tool-result images to the 5MB Anthropic limit to avoid hard request rejections.
- Agent runtime: align pi-agent-core imports and write v2 session headers so Pi session branching stays in the Clawdis sessions dir. - Agent runtime: write v2 session headers so Pi session branching stays in the Clawdis sessions dir.
- Tests: add Swift Testing coverage for camera errors and Kotest coverage for Android bridge endpoints. - Tests: add Swift Testing coverage for camera errors and Kotest coverage for Android bridge endpoints.
## 2.0.0-beta4 — 2025-12-27 ## 2.0.0-beta4 — 2025-12-27

View File

@@ -1,6 +1,6 @@
import { type ChildProcessWithoutNullStreams, spawn } from "node:child_process"; import { type ChildProcessWithoutNullStreams, spawn } from "node:child_process";
import { randomUUID } from "node:crypto"; import { randomUUID } from "node:crypto";
import type { AgentTool, AgentToolResult } from "@mariozechner/pi-agent-core"; import type { AgentTool, AgentToolResult } from "@mariozechner/pi-ai";
import { Type } from "@sinclair/typebox"; import { Type } from "@sinclair/typebox";
import { import {

View File

@@ -1,7 +1,7 @@
import crypto from "node:crypto"; import crypto from "node:crypto";
import fs from "node:fs/promises"; import fs from "node:fs/promises";
import type { AgentTool, AgentToolResult } from "@mariozechner/pi-agent-core"; import type { AgentTool, AgentToolResult } from "@mariozechner/pi-ai";
import { Type } from "@sinclair/typebox"; import { Type } from "@sinclair/typebox";
import { import {
browserCloseTab, browserCloseTab,

View File

@@ -1,11 +1,8 @@
import fs from "node:fs/promises"; import fs from "node:fs/promises";
import path from "node:path"; import path from "node:path";
import type { import type { AppMessage } from "@mariozechner/pi-agent-core";
AgentMessage, import type { AgentToolResult, AssistantMessage } from "@mariozechner/pi-ai";
AgentToolResult,
} from "@mariozechner/pi-agent-core";
import type { AssistantMessage } from "@mariozechner/pi-ai";
import { sanitizeContentBlocksImages } from "./tool-images.js"; import { sanitizeContentBlocksImages } from "./tool-images.js";
import type { WorkspaceBootstrapFile } from "./workspace.js"; import type { WorkspaceBootstrapFile } from "./workspace.js";
@@ -39,12 +36,12 @@ export async function ensureSessionHeader(params: {
type ContentBlock = AgentToolResult<unknown>["content"][number]; type ContentBlock = AgentToolResult<unknown>["content"][number];
export async function sanitizeSessionMessagesImages( export async function sanitizeSessionMessagesImages(
messages: AgentMessage[], messages: AppMessage[],
label: string, label: string,
): Promise<AgentMessage[]> { ): Promise<AppMessage[]> {
// We sanitize historical session messages because Anthropic can reject a request // We sanitize historical session messages because Anthropic can reject a request
// if the transcript contains oversized base64 images (see MAX_IMAGE_DIMENSION_PX). // if the transcript contains oversized base64 images (see MAX_IMAGE_DIMENSION_PX).
const out: AgentMessage[] = []; const out: AppMessage[] = [];
for (const msg of messages) { for (const msg of messages) {
if (!msg || typeof msg !== "object") { if (!msg || typeof msg !== "object") {
out.push(msg); out.push(msg);
@@ -53,7 +50,7 @@ export async function sanitizeSessionMessagesImages(
const role = (msg as { role?: unknown }).role; const role = (msg as { role?: unknown }).role;
if (role === "toolResult") { if (role === "toolResult") {
const toolMsg = msg as Extract<AgentMessage, { role: "toolResult" }>; const toolMsg = msg as Extract<AppMessage, { role: "toolResult" }>;
const content = Array.isArray(toolMsg.content) ? toolMsg.content : []; const content = Array.isArray(toolMsg.content) ? toolMsg.content : [];
const nextContent = (await sanitizeContentBlocksImages( const nextContent = (await sanitizeContentBlocksImages(
content as ContentBlock[], content as ContentBlock[],
@@ -64,7 +61,7 @@ export async function sanitizeSessionMessagesImages(
} }
if (role === "user") { if (role === "user") {
const userMsg = msg as Extract<AgentMessage, { role: "user" }>; const userMsg = msg as Extract<AppMessage, { role: "user" }>;
const content = userMsg.content; const content = userMsg.content;
if (Array.isArray(content)) { if (Array.isArray(content)) {
const nextContent = (await sanitizeContentBlocksImages( const nextContent = (await sanitizeContentBlocksImages(

View File

@@ -3,7 +3,7 @@ import fs from "node:fs/promises";
import os from "node:os"; import os from "node:os";
import path from "node:path"; import path from "node:path";
import type { AgentMessage, ThinkingLevel } from "@mariozechner/pi-agent-core"; import type { AppMessage, ThinkingLevel } from "@mariozechner/pi-agent-core";
import { import {
type Api, type Api,
type AssistantMessage, type AssistantMessage,
@@ -501,7 +501,7 @@ export async function runEmbeddedPiAgent(params: {
Math.max(1, params.timeoutMs), Math.max(1, params.timeoutMs),
); );
let messagesSnapshot: AgentMessage[] = []; let messagesSnapshot: AppMessage[] = [];
let sessionIdUsed = session.sessionId; let sessionIdUsed = session.sessionId;
const onAbort = () => { const onAbort = () => {
abortRun(); abortRun();
@@ -542,7 +542,7 @@ export async function runEmbeddedPiAgent(params: {
const lastAssistant = messagesSnapshot const lastAssistant = messagesSnapshot
.slice() .slice()
.reverse() .reverse()
.find((m) => (m as AgentMessage)?.role === "assistant") as .find((m) => (m as AppMessage)?.role === "assistant") as
| AssistantMessage | AssistantMessage
| undefined; | undefined;

View File

@@ -1,4 +1,4 @@
import type { AgentEvent, AgentMessage } from "@mariozechner/pi-agent-core"; import type { AgentEvent, AppMessage } from "@mariozechner/pi-agent-core";
import type { AssistantMessage } from "@mariozechner/pi-ai"; import type { AssistantMessage } from "@mariozechner/pi-ai";
import type { AgentSession } from "@mariozechner/pi-coding-agent"; import type { AgentSession } from "@mariozechner/pi-coding-agent";
@@ -234,7 +234,7 @@ export function subscribeEmbeddedPiSession(params: {
} }
if (evt.type === "message_update") { if (evt.type === "message_update") {
const msg = (evt as AgentEvent & { message: AgentMessage }).message; const msg = (evt as AgentEvent & { message: AppMessage }).message;
if (msg?.role === "assistant") { if (msg?.role === "assistant") {
const assistantEvent = ( const assistantEvent = (
evt as AgentEvent & { assistantMessageEvent?: unknown } evt as AgentEvent & { assistantMessageEvent?: unknown }
@@ -298,7 +298,7 @@ export function subscribeEmbeddedPiSession(params: {
} }
if (evt.type === "message_end") { if (evt.type === "message_end") {
const msg = (evt as AgentEvent & { message: AgentMessage }).message; const msg = (evt as AgentEvent & { message: AppMessage }).message;
if (msg?.role === "assistant") { if (msg?.role === "assistant") {
const cleaned = params.enforceFinalTag const cleaned = params.enforceFinalTag
? stripThinkingSegments( ? stripThinkingSegments(

View File

@@ -1,4 +1,4 @@
import type { AgentTool, AgentToolResult } from "@mariozechner/pi-agent-core"; import type { AgentTool, AgentToolResult } from "@mariozechner/pi-ai";
import { codingTools, readTool } from "@mariozechner/pi-coding-agent"; import { codingTools, readTool } from "@mariozechner/pi-coding-agent";
import { Type } from "@sinclair/typebox"; import { Type } from "@sinclair/typebox";

View File

@@ -1,4 +1,4 @@
import type { AgentToolResult } from "@mariozechner/pi-agent-core"; import type { AgentToolResult } from "@mariozechner/pi-ai";
import { getImageMetadata, resizeToJpeg } from "../media/image-ops.js"; import { getImageMetadata, resizeToJpeg } from "../media/image-ops.js";