repositories / pi-ext
pi-ext
bugabingas pi extensions
owned by admin
extensions/ultra/call.ts
Raw// Streaming arguments are unvalidated and may stop at any field.
// This view only reads received data; it never resolves or executes a workflow.
import { stripVTControlCharacters } from "node:util";
import {
keyHint,
type Theme,
type ToolDefinition,
} from "@earendil-works/pi-coding-agent";
import {
type Component,
truncateToWidth,
wrapTextWithAnsi,
} from "@earendil-works/pi-tui";
type CallOptions = Pick<
Parameters<NonNullable<ToolDefinition["renderCall"]>>[2],
"expanded" | "argsComplete" | "executionStarted" | "isPartial" | "isError"
>;
function record(value: unknown): Record<string, unknown> | undefined {
return value !== null && typeof value === "object" && !Array.isArray(value)
? (value as Record<string, unknown>)
: undefined;
}
function plain(value: string): string {
return stripVTControlCharacters(value)
.replace(/[\x00-\x08\x0b-\x1f\x7f]/g, "")
.replaceAll("\t", " ");
}
function line(value: unknown): string {
return typeof value === "string"
? plain(value).replace(/\s+/g, " ").trim()
: "";
}
/** Like Pi's write preview, text advances with argument updates, without timers. */
export function renderUltraCall(
args: unknown,
theme: Theme,
options: CallOptions,
): Component {
return {
render(width) {
const w = Math.max(1, width);
const input = record(args);
const inline = input?.spec !== undefined;
const spec = record(input?.spec);
const name = line(inline ? spec?.name : input?.name);
const phases = Array.isArray(spec?.phases) ? spec.phases : [];
const started =
options.executionStarted || options.isError || !options.isPartial;
const receiving = !started && !options.argsComplete;
const rows: string[] = [];
const add = (text: string, color: Parameters<Theme["fg"]>[0] = "muted") =>
rows.push(theme.fg(color, truncateToWidth(text, w)));
const block = (text: string) => {
for (const row of wrapTextWithAnsi(plain(text), Math.max(1, w - 3)))
add(` ${row}`, "toolOutput");
};
add(
`${theme.bold("run_workflow")}${name ? ` ${name}` : ""}`,
"toolTitle",
);
// The execution board owns the collapsed row after handoff, including errors.
if (started && !options.expanded) return rows;
const status = started
? "Received workflow"
: receiving
? "Drafting workflow"
: "Arguments received";
if (inline) {
add(
`${status} · ${phases.length} phase${phases.length === 1 ? "" : "s"} received${receiving ? " · no agents running" : ""}`,
);
} else if (name) {
const inputs = record(input?.args);
const count = inputs ? Object.keys(inputs).length : 0;
add(
`Saved workflow · ${count} input${count === 1 ? "" : "s"} received`,
);
} else
add(receiving ? "Receiving workflow arguments…" : "Arguments received");
if (!started && !receiving)
add("Awaiting validation and execution.", "dim");
if (options.expanded && line(spec?.description))
block(line(spec?.description));
// Keep the receiving end visible when a workflow has many phases.
const first = options.expanded ? 0 : Math.max(0, phases.length - 3);
if (first > 0)
add(`… ${first} earlier phase${first === 1 ? "" : "s"}`, "dim");
for (let index = first; index < phases.length; index++) {
const phase = record(phases[index]);
const step = record(phase?.step);
const kind = line(phase?.kind);
const fanout =
kind === "fanout"
? Array.isArray(phase?.over)
? `${phase.over.length} items received`
: line(phase?.over)
? "dynamic items"
: "items not received"
: "";
add(
[
`${index + 1} ${line(phase?.id) || "unnamed phase"}`,
kind || "kind not received",
fanout,
line(step?.model),
line(phase?.when) ? "conditional" : "",
]
.filter(Boolean)
.join(" · "),
"accent",
);
add(
` ${line(step?.summary) || "Summary not received"}`,
"toolOutput",
);
if (!options.expanded) continue;
const tools = Array.isArray(step?.tools)
? step.tools.map(line).filter(Boolean)
: undefined;
if (tools) block(`tools: ${tools.join(", ") || "none"}`);
if (line(step?.thinkingLevel))
block(`thinking: ${line(step?.thinkingLevel)}`);
if (kind === "fanout" && line(phase?.over))
block(`over: ${line(phase?.over)}`);
if (line(phase?.when)) block(`when: ${line(phase?.when)}`);
if (typeof step?.prompt === "string") {
add(" Received prompt", "dim");
block(step.prompt);
}
}
if (options.expanded && line(spec?.return))
block(`return: ${line(spec?.return)}`);
if (!options.expanded && phases.length > 0)
add(keyHint("app.tools.expand", "to expand"), "dim");
return rows;
},
invalidate() {},
};
}