chore: reformat
This commit is contained in:
@@ -1108,7 +1108,7 @@ export class Agent {
|
||||
|
||||
/** Calculate total text length from an assistant message's content blocks */
|
||||
#getAssistantTextLength(message: AgentMessage | null): number {
|
||||
if (!message || message.role !== "assistant" || !Array.isArray(message.content)) {
|
||||
if (message?.role !== "assistant" || !Array.isArray(message.content)) {
|
||||
return 0;
|
||||
}
|
||||
let length = 0;
|
||||
|
||||
@@ -230,7 +230,7 @@ export function recoverHarmonyToolCall(
|
||||
): HarmonyRecoveredToolCall | undefined {
|
||||
if (detection.surface !== "tool_arg" || detection.contentIndex === undefined) return undefined;
|
||||
const block = message.content[detection.contentIndex];
|
||||
if (!block || block.type !== "toolCall") return undefined;
|
||||
if (block?.type !== "toolCall") return undefined;
|
||||
|
||||
const config = RECOVERY_REGISTRY[block.name];
|
||||
if (!config) return undefined;
|
||||
|
||||
@@ -334,7 +334,7 @@ describe("agentLoop with AgentMessage", () => {
|
||||
}
|
||||
const partial = makeMessage(index);
|
||||
const toolCall = partial.content[index - 1];
|
||||
if (!toolCall || toolCall.type !== "toolCall") throw new Error("Expected tool call");
|
||||
if (toolCall?.type !== "toolCall") throw new Error("Expected tool call");
|
||||
stream.push({ type: "toolcall_start", contentIndex: index - 1, partial });
|
||||
stream.push({
|
||||
type: "toolcall_delta",
|
||||
@@ -371,7 +371,7 @@ describe("agentLoop with AgentMessage", () => {
|
||||
event.type === "turn_end" && event.toolResults.length === 8,
|
||||
);
|
||||
expect(batchedTurn).toBeDefined();
|
||||
if (!batchedTurn || batchedTurn.message.role !== "assistant") return;
|
||||
if (batchedTurn?.message.role !== "assistant") return;
|
||||
expect(batchedTurn.message.stopReason).toBe("toolUse");
|
||||
expect(batchedTurn.message.content.filter(block => block.type === "toolCall")).toHaveLength(8);
|
||||
expect(batchedTurn.toolResults.map(result => result.toolCallId).sort()).toEqual([
|
||||
@@ -571,7 +571,7 @@ describe("agentLoop with AgentMessage", () => {
|
||||
e.type === "message_end" && e.message.role === "toolResult",
|
||||
);
|
||||
expect(toolResultEvent).toBeDefined();
|
||||
if (!toolResultEvent || toolResultEvent.message.role !== "toolResult") return;
|
||||
if (toolResultEvent?.message.role !== "toolResult") return;
|
||||
expect(toolResultEvent.message.isError).toBe(true);
|
||||
expect(toolResultEvent.message.toolCallId).toBe("tool-1");
|
||||
expect(toolResultEvent.message.content[0]?.type).toBe("text");
|
||||
|
||||
@@ -281,7 +281,7 @@ export class RemoteAuthCredentialStore implements AuthCredentialStore {
|
||||
|
||||
async prepareForRequest(credentialId: number, opts: { signal?: AbortSignal } = {}): Promise<boolean> {
|
||||
const entry = this.#snapshot.credentials.find(candidate => candidate.id === credentialId);
|
||||
if (!entry || entry.credential.type !== "oauth" || entry.rotatesInMs === null) return false;
|
||||
if (entry?.credential.type !== "oauth" || entry.rotatesInMs === null) return false;
|
||||
const remainingMs = this.#snapshotReceivedAt + entry.rotatesInMs - Date.now();
|
||||
if (remainingMs > WAIT_THRESHOLD_MS) return false;
|
||||
return this.waitForFreshSnapshot(MAX_WAIT_MS, opts);
|
||||
|
||||
@@ -2984,7 +2984,7 @@ export class AuthStorage {
|
||||
if (!prepare) return true;
|
||||
const stored = this.#getStoredCredentials(provider);
|
||||
const selected = stored[selection.index];
|
||||
if (!selected || selected.credential.type !== "oauth") return false;
|
||||
if (selected?.credential.type !== "oauth") return false;
|
||||
|
||||
const prepared = await prepare(selected.id, { signal: options?.signal });
|
||||
if (!prepared) return true;
|
||||
@@ -2996,7 +2996,7 @@ export class AuthStorage {
|
||||
const latestIndex = latestRows.findIndex(row => row.id === selected.id);
|
||||
if (latestIndex === -1) return false;
|
||||
const latest = latestRows[latestIndex];
|
||||
if (!latest || latest.credential.type !== "oauth") return false;
|
||||
if (latest?.credential.type !== "oauth") return false;
|
||||
selection.index = latestIndex;
|
||||
selection.credential = latest.credential;
|
||||
return true;
|
||||
|
||||
@@ -1775,7 +1775,7 @@ function disableThinkingIfToolChoiceForced(params: MessageCreateParamsStreaming)
|
||||
|
||||
function ensureMaxTokensForThinking(params: MessageCreateParamsStreaming, model: Model<"anthropic-messages">): void {
|
||||
const thinking = params.thinking;
|
||||
if (!thinking || thinking.type !== "enabled") return;
|
||||
if (thinking?.type !== "enabled") return;
|
||||
|
||||
const budgetTokens = thinking.budget_tokens ?? 0;
|
||||
if (budgetTokens <= 0) return;
|
||||
|
||||
@@ -586,7 +586,7 @@ export const streamOpenAICompletions: StreamFunction<"openai-completions"> = (
|
||||
eventStream: AssistantMessageEventStream,
|
||||
text: string,
|
||||
): void => {
|
||||
if (!currentBlock || currentBlock.type !== "text") {
|
||||
if (currentBlock?.type !== "text") {
|
||||
finishCurrentBlock(currentBlock);
|
||||
currentBlock = { type: "text", text: "" };
|
||||
message.content.push(currentBlock);
|
||||
@@ -607,8 +607,7 @@ export const streamOpenAICompletions: StreamFunction<"openai-completions"> = (
|
||||
signature?: string,
|
||||
): void => {
|
||||
if (
|
||||
!currentBlock ||
|
||||
currentBlock.type !== "thinking" ||
|
||||
currentBlock?.type !== "thinking" ||
|
||||
(signature !== undefined && currentBlock.thinkingSignature !== signature)
|
||||
) {
|
||||
finishCurrentBlock(currentBlock);
|
||||
@@ -815,7 +814,7 @@ export const streamOpenAICompletions: StreamFunction<"openai-completions"> = (
|
||||
}
|
||||
|
||||
if (!block) {
|
||||
if (!currentBlock || currentBlock.type !== "toolCall") {
|
||||
if (currentBlock?.type !== "toolCall") {
|
||||
finishCurrentBlock(currentBlock);
|
||||
}
|
||||
block = {
|
||||
|
||||
@@ -954,7 +954,7 @@ export function encodeStream(
|
||||
break;
|
||||
}
|
||||
case "text_delta": {
|
||||
if (!state.open || state.open.kind !== "message") break;
|
||||
if (state.open?.kind !== "message") break;
|
||||
const cur: OpenMessage = state.open;
|
||||
cur.currentPartText += ev.delta;
|
||||
emit("response.output_text.delta", {
|
||||
@@ -970,7 +970,7 @@ export function encodeStream(
|
||||
break;
|
||||
}
|
||||
case "text_end": {
|
||||
if (!state.open || state.open.kind !== "message") break;
|
||||
if (state.open?.kind !== "message") break;
|
||||
const cur: OpenMessage = state.open;
|
||||
const text = ev.content ?? cur.currentPartText;
|
||||
emit("response.output_text.done", {
|
||||
@@ -997,7 +997,7 @@ export function encodeStream(
|
||||
break;
|
||||
}
|
||||
case "thinking_delta": {
|
||||
if (!state.open || state.open.kind !== "reasoning") break;
|
||||
if (state.open?.kind !== "reasoning") break;
|
||||
const cur: OpenReasoning = state.open;
|
||||
cur.reasoningText += ev.delta;
|
||||
emit("response.reasoning_summary_text.delta", {
|
||||
@@ -1009,7 +1009,7 @@ export function encodeStream(
|
||||
break;
|
||||
}
|
||||
case "thinking_end": {
|
||||
if (!state.open || state.open.kind !== "reasoning") break;
|
||||
if (state.open?.kind !== "reasoning") break;
|
||||
const cur: OpenReasoning = state.open;
|
||||
const text = ev.content ?? cur.reasoningText;
|
||||
cur.reasoningText = text;
|
||||
@@ -1034,7 +1034,7 @@ export function encodeStream(
|
||||
break;
|
||||
}
|
||||
case "toolcall_delta": {
|
||||
if (!state.open || state.open.kind !== "function_call") break;
|
||||
if (state.open?.kind !== "function_call") break;
|
||||
const cur: OpenFunctionCall = state.open;
|
||||
cur.argsText += ev.delta;
|
||||
if (cur.customWireName) {
|
||||
@@ -1053,7 +1053,7 @@ export function encodeStream(
|
||||
break;
|
||||
}
|
||||
case "toolcall_end": {
|
||||
if (!state.open || state.open.kind !== "function_call") break;
|
||||
if (state.open?.kind !== "function_call") break;
|
||||
const cur: OpenFunctionCall = state.open;
|
||||
// Promote possibly-late info from the canonical ToolCall.
|
||||
const tc = ev.toolCall;
|
||||
|
||||
@@ -428,7 +428,7 @@ describe("anthropic stream envelope handling", () => {
|
||||
|
||||
const toolCall = result.content[0];
|
||||
expect(toolCall?.type).toBe("toolCall");
|
||||
if (!toolCall || toolCall.type !== "toolCall") {
|
||||
if (toolCall?.type !== "toolCall") {
|
||||
throw new Error("Expected toolCall content in terminal error payload");
|
||||
}
|
||||
expect("partialJson" in toolCall).toBe(false);
|
||||
|
||||
@@ -167,7 +167,7 @@ describe("auth-gateway openai-chat: parseRequest", () => {
|
||||
],
|
||||
});
|
||||
const tool = parsed.context.messages.find(m => m.role === "toolResult");
|
||||
if (!tool || tool.role !== "toolResult") throw new Error("expected toolResult");
|
||||
if (tool?.role !== "toolResult") throw new Error("expected toolResult");
|
||||
expect(tool.toolName).toBe("submit_move");
|
||||
});
|
||||
|
||||
@@ -184,7 +184,7 @@ describe("auth-gateway openai-chat: parseRequest", () => {
|
||||
],
|
||||
});
|
||||
const tool = parsed.context.messages.find(m => m.role === "toolResult");
|
||||
if (!tool || tool.role !== "toolResult") throw new Error("expected toolResult");
|
||||
if (tool?.role !== "toolResult") throw new Error("expected toolResult");
|
||||
expect(tool.toolName).toBe("submit_move");
|
||||
});
|
||||
|
||||
@@ -198,7 +198,7 @@ describe("auth-gateway openai-chat: parseRequest", () => {
|
||||
],
|
||||
});
|
||||
const tool = parsed.context.messages.find(m => m.role === "toolResult");
|
||||
if (!tool || tool.role !== "toolResult") throw new Error("expected toolResult");
|
||||
if (tool?.role !== "toolResult") throw new Error("expected toolResult");
|
||||
expect(tool.toolName).toBe("");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -70,7 +70,7 @@ describe("AuthStorage api-key login replacement", () => {
|
||||
expect(credentials).toHaveLength(1);
|
||||
const [stored] = credentials;
|
||||
expect(stored?.credential.type).toBe("api_key");
|
||||
if (!stored || stored.credential.type !== "api_key") {
|
||||
if (stored?.credential.type !== "api_key") {
|
||||
throw new Error("expected stored api-key credential");
|
||||
}
|
||||
expect(stored.credential.key).toBe("same-kagi-key");
|
||||
@@ -96,7 +96,7 @@ describe("AuthStorage api-key login replacement", () => {
|
||||
expect(credentials).toHaveLength(1);
|
||||
const [stored] = credentials;
|
||||
expect(stored?.credential.type).toBe("api_key");
|
||||
if (!stored || stored.credential.type !== "api_key") {
|
||||
if (stored?.credential.type !== "api_key") {
|
||||
throw new Error("expected stored api-key credential");
|
||||
}
|
||||
expect(stored.credential.key).toBe("same-ollama-cloud-key");
|
||||
@@ -122,7 +122,7 @@ describe("AuthStorage api-key login replacement", () => {
|
||||
expect(credentials).toHaveLength(1);
|
||||
const [stored] = credentials;
|
||||
expect(stored?.credential.type).toBe("api_key");
|
||||
if (!stored || stored.credential.type !== "api_key") {
|
||||
if (stored?.credential.type !== "api_key") {
|
||||
throw new Error("expected stored api-key credential");
|
||||
}
|
||||
expect(stored.credential.key).toBe("same-deepseek-key");
|
||||
|
||||
@@ -151,7 +151,7 @@ describe("AuthStorage openai-codex email dedupe", () => {
|
||||
expect(credentials).toHaveLength(1);
|
||||
const [remaining] = credentials;
|
||||
expect(remaining?.credential.type).toBe("oauth");
|
||||
if (!remaining || remaining.credential.type !== "oauth") throw new Error("expected oauth credential");
|
||||
if (remaining?.credential.type !== "oauth") throw new Error("expected oauth credential");
|
||||
expect(remaining.credential.accountId).toBe("account-b");
|
||||
expect(remaining.credential.email).toBe("shared.user@example.com");
|
||||
});
|
||||
@@ -168,7 +168,7 @@ describe("AuthStorage openai-codex email dedupe", () => {
|
||||
expect(credentials).toHaveLength(1);
|
||||
const [remaining] = credentials;
|
||||
expect(remaining?.credential.type).toBe("oauth");
|
||||
if (!remaining || remaining.credential.type !== "oauth") throw new Error("expected oauth credential");
|
||||
if (remaining?.credential.type !== "oauth") throw new Error("expected oauth credential");
|
||||
expect(remaining.credential.accountId).toBe("account-b");
|
||||
});
|
||||
|
||||
@@ -207,7 +207,7 @@ describe("AuthStorage openai-codex email dedupe", () => {
|
||||
expect(credentials).toHaveLength(1);
|
||||
const [remaining] = credentials;
|
||||
expect(remaining?.credential.type).toBe("oauth");
|
||||
if (!remaining || remaining.credential.type !== "oauth") throw new Error("expected oauth credential");
|
||||
if (remaining?.credential.type !== "oauth") throw new Error("expected oauth credential");
|
||||
expect(remaining.credential.accountId).toBe("account-b");
|
||||
expect(remaining.credential.email).toBe("shared.user@example.com");
|
||||
expect(readDisabledCauses(dbPath, "openai-codex")).toEqual([]);
|
||||
@@ -300,7 +300,7 @@ describe("AuthStorage openai-codex email dedupe", () => {
|
||||
expect(credentials).toHaveLength(1);
|
||||
const [remaining] = credentials;
|
||||
expect(remaining?.credential.type).toBe("oauth");
|
||||
if (!remaining || remaining.credential.type !== "oauth") throw new Error("expected oauth credential");
|
||||
if (remaining?.credential.type !== "oauth") throw new Error("expected oauth credential");
|
||||
expect(remaining.credential.accountId).toBe("account-b");
|
||||
});
|
||||
|
||||
@@ -319,7 +319,7 @@ describe("AuthStorage openai-codex email dedupe", () => {
|
||||
expect(credentials).toHaveLength(1);
|
||||
const [remaining] = credentials;
|
||||
expect(remaining?.credential.type).toBe("oauth");
|
||||
if (!remaining || remaining.credential.type !== "oauth") throw new Error("expected oauth credential");
|
||||
if (remaining?.credential.type !== "oauth") throw new Error("expected oauth credential");
|
||||
expect(remaining.credential.accountId).toBe("account-b");
|
||||
expect(remaining.credential.email).toBe("shared.user@example.com");
|
||||
});
|
||||
@@ -350,7 +350,7 @@ describe("AuthStorage openai-codex email dedupe", () => {
|
||||
expect(credentials).toHaveLength(1);
|
||||
const [remaining] = credentials;
|
||||
expect(remaining?.credential.type).toBe("oauth");
|
||||
if (!remaining || remaining.credential.type !== "oauth") throw new Error("expected oauth credential");
|
||||
if (remaining?.credential.type !== "oauth") throw new Error("expected oauth credential");
|
||||
expect(remaining.credential.accountId).toBe("org-b");
|
||||
expect(remaining.credential.email).toBe("shared.user@example.com");
|
||||
});
|
||||
|
||||
@@ -142,7 +142,7 @@ describe("Cursor request action encoding", () => {
|
||||
expect(userMessage?.selectedContext?.selectedImages).toHaveLength(1);
|
||||
const selectedImage = userMessage?.selectedContext?.selectedImages[0];
|
||||
expect(selectedImage?.mimeType).toBe("image/png");
|
||||
if (!selectedImage || selectedImage.dataOrBlobId.case !== "data") {
|
||||
if (selectedImage?.dataOrBlobId.case !== "data") {
|
||||
throw new Error("Expected Cursor selected image data");
|
||||
}
|
||||
expect(Array.from(selectedImage.dataOrBlobId.value)).toEqual(Array.from(Buffer.from(imageData, "base64")));
|
||||
|
||||
@@ -63,7 +63,7 @@ async function handleToolWithImageResult<TApi extends Api>(model: Model<TApi>, o
|
||||
// Find the tool call
|
||||
const toolCall = firstResponse.content.find(b => b.type === "toolCall");
|
||||
expect(toolCall).toBeTruthy();
|
||||
if (!toolCall || toolCall.type !== "toolCall") {
|
||||
if (toolCall?.type !== "toolCall") {
|
||||
throw new Error("Expected tool call");
|
||||
}
|
||||
expect(toolCall.name).toBe("get_circle");
|
||||
@@ -152,7 +152,7 @@ async function handleToolWithTextAndImageResult<TApi extends Api>(model: Model<T
|
||||
// Find the tool call
|
||||
const toolCall = firstResponse.content.find(b => b.type === "toolCall");
|
||||
expect(toolCall).toBeTruthy();
|
||||
if (!toolCall || toolCall.type !== "toolCall") {
|
||||
if (toolCall?.type !== "toolCall") {
|
||||
throw new Error("Expected tool call");
|
||||
}
|
||||
expect(toolCall.name).toBe("get_circle_with_description");
|
||||
|
||||
@@ -121,7 +121,7 @@ describe("openai-completions compatibility", () => {
|
||||
const messages = convertMessages(model, { messages: [assistantMessage] }, compat);
|
||||
const assistant = messages.find(message => message.role === "assistant");
|
||||
expect(assistant).toBeDefined();
|
||||
if (!assistant || assistant.role !== "assistant") {
|
||||
if (assistant?.role !== "assistant") {
|
||||
throw new Error("assistant message missing");
|
||||
}
|
||||
expect(typeof assistant.content).toBe("string");
|
||||
|
||||
@@ -178,8 +178,7 @@ export function rewriteImports(code: string): string {
|
||||
if (node.type !== "CallExpression") return;
|
||||
const call = node as unknown as { callee?: { type?: string; start?: number; end?: number } };
|
||||
const callee = call.callee;
|
||||
if (!callee || callee.type !== "Import" || typeof callee.start !== "number" || typeof callee.end !== "number")
|
||||
return;
|
||||
if (callee?.type !== "Import" || typeof callee.start !== "number" || typeof callee.end !== "number") return;
|
||||
edits.push({ start: callee.start, end: callee.end, text: "__omp_import__" });
|
||||
});
|
||||
|
||||
@@ -252,12 +251,7 @@ export function rewriteDynamicImports(code: string, callee = "__omp_import__"):
|
||||
if (node.type !== "CallExpression") return;
|
||||
const call = node as unknown as { callee?: { type?: string; start?: number; end?: number } };
|
||||
const callCallee = call.callee;
|
||||
if (
|
||||
!callCallee ||
|
||||
callCallee.type !== "Import" ||
|
||||
typeof callCallee.start !== "number" ||
|
||||
typeof callCallee.end !== "number"
|
||||
) {
|
||||
if (callCallee?.type !== "Import" || typeof callCallee.start !== "number" || typeof callCallee.end !== "number") {
|
||||
return;
|
||||
}
|
||||
edits.push({ start: callCallee.start, end: callCallee.end, text: callee });
|
||||
|
||||
@@ -103,7 +103,7 @@ export function renderResult(
|
||||
args?: LspParams,
|
||||
): Component {
|
||||
const content = result.content?.[0];
|
||||
if (!content || content.type !== "text" || !("text" in content) || !content.text) {
|
||||
if (content?.type !== "text" || !("text" in content) || !content.text) {
|
||||
const icon = formatStatusIcon("warning", theme, options.spinnerFrame);
|
||||
const header = `${icon} LSP`;
|
||||
return new Text([header, theme.fg("dim", "No result")].join("\n"), 0, 0);
|
||||
|
||||
@@ -42,7 +42,7 @@ function getUriPort(uri: URL): number {
|
||||
|
||||
function validateRedirectConfig(config: MCPOAuthConfig, redirectUri: string | undefined): void {
|
||||
const parsed = parseRedirectUri(redirectUri);
|
||||
if (!parsed || parsed.protocol !== "https:" || !isLoopbackHostname(parsed.hostname)) {
|
||||
if (parsed?.protocol !== "https:" || !isLoopbackHostname(parsed.hostname)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ function resolveCallbackPort(callbackPort: number | undefined, redirectUri: stri
|
||||
if (callbackPort !== undefined) return callbackPort;
|
||||
|
||||
const parsed = parseRedirectUri(redirectUri);
|
||||
if (!parsed || parsed.protocol !== "http:" || !isLoopbackHostname(parsed.hostname)) {
|
||||
if (parsed?.protocol !== "http:" || !isLoopbackHostname(parsed.hostname)) {
|
||||
return DEFAULT_PORT;
|
||||
}
|
||||
|
||||
|
||||
@@ -266,7 +266,7 @@ async function elicitFromAcpClient(
|
||||
finish(undefined);
|
||||
});
|
||||
const response = await promise;
|
||||
if (!response || response.action !== "accept" || !response.content) {
|
||||
if (response?.action !== "accept" || !response.content) {
|
||||
return undefined;
|
||||
}
|
||||
return response.content.value;
|
||||
|
||||
@@ -121,7 +121,7 @@ function matchAgent(agent: DashboardAgent, query: string): boolean {
|
||||
function extractAssistantText(messages: AgentMessage[]): string | null {
|
||||
for (let i = messages.length - 1; i >= 0; i--) {
|
||||
const message = messages[i];
|
||||
if (!message || message.role !== "assistant") continue;
|
||||
if (message?.role !== "assistant") continue;
|
||||
const blocks = message.content;
|
||||
if (!Array.isArray(blocks)) continue;
|
||||
const text = blocks
|
||||
|
||||
@@ -151,7 +151,7 @@ export function renderDiff(diffText: string, options: RenderDiffOptions = {}): s
|
||||
const removedLines: { lineNum: string; content: string }[] = [];
|
||||
while (i < lines.length) {
|
||||
const p = parseDiffLine(lines[i]);
|
||||
if (!p || p.prefix !== "-") break;
|
||||
if (p?.prefix !== "-") break;
|
||||
removedLines.push({ lineNum: p.lineNum, content: p.content });
|
||||
i++;
|
||||
}
|
||||
@@ -159,7 +159,7 @@ export function renderDiff(diffText: string, options: RenderDiffOptions = {}): s
|
||||
const addedLines: { lineNum: string; content: string }[] = [];
|
||||
while (i < lines.length) {
|
||||
const p = parseDiffLine(lines[i]);
|
||||
if (!p || p.prefix !== "+") break;
|
||||
if (p?.prefix !== "+") break;
|
||||
addedLines.push({ lineNum: p.lineNum, content: p.content });
|
||||
i++;
|
||||
}
|
||||
|
||||
@@ -9,3 +9,4 @@ Did you know? Each kitty/tmux split keeps its own session — `omp -c` resumes t
|
||||
Drop the word `ultrathink` in your message for harder multi-step reasoning — watch it glow rainbow as you type
|
||||
Say `orchestrate` in your message to drive a multi-phase task with parallel subagents — watch it glow as you type
|
||||
Log in to several accounts of the same provider — `/login` again — and omp load-balances across them automatically
|
||||
Run `omp auth-broker serve` once and every machine pulls live tokens over the wire — refresh keys never leave the host; `omp auth-gateway` fronts it as a drop-in proxy any OpenAI-compatible client can hit
|
||||
@@ -6227,7 +6227,7 @@ export class AgentSession {
|
||||
|
||||
#closeCodexProviderSessionsForHistoryRewrite(): void {
|
||||
const currentModel = this.model;
|
||||
if (!currentModel || currentModel.api !== "openai-codex-responses") return;
|
||||
if (currentModel?.api !== "openai-codex-responses") return;
|
||||
this.#closeProviderSessionsForModelSwitch(currentModel, currentModel);
|
||||
}
|
||||
|
||||
@@ -8366,7 +8366,7 @@ export class AgentSession {
|
||||
const previousSessionFile = this.sessionFile;
|
||||
const selectedEntry = this.sessionManager.getEntry(entryId);
|
||||
|
||||
if (!selectedEntry || selectedEntry.type !== "message" || selectedEntry.message.role !== "user") {
|
||||
if (selectedEntry?.type !== "message" || selectedEntry.message.role !== "user") {
|
||||
throw new Error("Invalid entry ID for branching");
|
||||
}
|
||||
|
||||
|
||||
@@ -917,7 +917,7 @@ export class WorkerCore {
|
||||
dispatchEvent: (event: unknown) => boolean;
|
||||
}
|
||||
const select = el as unknown as SelectLike;
|
||||
if (!select || select.tagName !== "SELECT") throw new Error("tab.select() requires a <select> element");
|
||||
if (select?.tagName !== "SELECT") throw new Error("tab.select() requires a <select> element");
|
||||
const EventCtor = (
|
||||
globalThis as unknown as { Event: new (type: string, init?: { bubbles: boolean }) => unknown }
|
||||
).Event;
|
||||
|
||||
@@ -1893,12 +1893,9 @@ describe("ACP agent", () => {
|
||||
// only `"sessionId" in call` picks the session-scoped variant — and
|
||||
// loop-style narrows don't propagate to the assertions below.
|
||||
const [first, second, third] = calls;
|
||||
if (!first || first.mode !== "form" || !("sessionId" in first))
|
||||
throw new Error("first call missing sessionId");
|
||||
if (!second || second.mode !== "form" || !("sessionId" in second))
|
||||
throw new Error("second call missing sessionId");
|
||||
if (!third || third.mode !== "form" || !("sessionId" in third))
|
||||
throw new Error("third call missing sessionId");
|
||||
if (first?.mode !== "form" || !("sessionId" in first)) throw new Error("first call missing sessionId");
|
||||
if (second?.mode !== "form" || !("sessionId" in second)) throw new Error("second call missing sessionId");
|
||||
if (third?.mode !== "form" || !("sessionId" in third)) throw new Error("third call missing sessionId");
|
||||
expect(first.sessionId).toBe("session-before-switch");
|
||||
expect(second.sessionId).toBe("session-after-switch");
|
||||
expect(third.sessionId).toBe("session-after-switch");
|
||||
|
||||
@@ -106,7 +106,7 @@ describe("AgentSession before_agent_start attribution fallback", () => {
|
||||
expect(emitBeforeAgentStart).toHaveBeenCalledTimes(1);
|
||||
const injectedMessage = findBeforeStartInjection(session.messages);
|
||||
expect(injectedMessage).toBeDefined();
|
||||
if (!injectedMessage || injectedMessage.role !== "custom") {
|
||||
if (injectedMessage?.role !== "custom") {
|
||||
throw new Error("Expected injected custom message in session state");
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ describe("AgentSession before_agent_start attribution fallback", () => {
|
||||
expect(emitBeforeAgentStart).toHaveBeenCalledTimes(1);
|
||||
const injectedMessage = findBeforeStartInjection(session.messages);
|
||||
expect(injectedMessage).toBeDefined();
|
||||
if (!injectedMessage || injectedMessage.role !== "custom") {
|
||||
if (injectedMessage?.role !== "custom") {
|
||||
throw new Error("Expected injected custom message in session state");
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ describe("AgentSession before_agent_start attribution fallback", () => {
|
||||
const promptMessage = findPromptMessage(session.messages, promptText);
|
||||
expect(promptMessage).toBeDefined();
|
||||
expect(promptMessage?.role).toBe("user");
|
||||
if (!promptMessage || promptMessage.role !== "user") {
|
||||
if (promptMessage?.role !== "user") {
|
||||
throw new Error("Expected delegated prompt to remain a user-role message");
|
||||
}
|
||||
expect(promptMessage.attribution).toBe("agent");
|
||||
|
||||
@@ -12,7 +12,7 @@ import { TempDir } from "@oh-my-pi/pi-utils";
|
||||
|
||||
function lastAgentMessage(session: AgentSession): AssistantMessage {
|
||||
const message = session.agent.state.messages.at(-1);
|
||||
if (!message || message.role !== "assistant") {
|
||||
if (message?.role !== "assistant") {
|
||||
throw new Error("Expected trailing assistant message");
|
||||
}
|
||||
return message as AssistantMessage;
|
||||
|
||||
@@ -152,7 +152,7 @@ function findRuntimeAssistant(session: AgentSession, text: string): AssistantMes
|
||||
const message = session.messages.find(
|
||||
candidate => candidate.role === "assistant" && getTextContent(candidate) === text,
|
||||
);
|
||||
if (!message || message.role !== "assistant") {
|
||||
if (message?.role !== "assistant") {
|
||||
throw new Error(`Expected runtime assistant message with text: ${text}`);
|
||||
}
|
||||
return message;
|
||||
@@ -164,19 +164,19 @@ function expectAssistantReplayMetadataSanitized(message: AssistantMessage): void
|
||||
expect(message.providerPayload).toBeUndefined();
|
||||
|
||||
const thinkingBlock = message.content.find(block => block.type === "thinking");
|
||||
if (!thinkingBlock || thinkingBlock.type !== "thinking") {
|
||||
if (thinkingBlock?.type !== "thinking") {
|
||||
throw new Error("Expected assistant thinking block");
|
||||
}
|
||||
expect(thinkingBlock.thinkingSignature).toBeUndefined();
|
||||
|
||||
const textBlock = message.content.find(block => block.type === "text");
|
||||
if (!textBlock || textBlock.type !== "text") {
|
||||
if (textBlock?.type !== "text") {
|
||||
throw new Error("Expected assistant text block");
|
||||
}
|
||||
expect(textBlock.textSignature).toBe("text_sig_preserved");
|
||||
|
||||
const toolCallBlock = message.content.find(block => block.type === "toolCall");
|
||||
if (!toolCallBlock || toolCallBlock.type !== "toolCall") {
|
||||
if (toolCallBlock?.type !== "toolCall") {
|
||||
throw new Error("Expected assistant tool call block");
|
||||
}
|
||||
expect(toolCallBlock).toMatchObject({
|
||||
@@ -299,7 +299,7 @@ describe("AgentSession OpenAI Responses replay boundaries", () => {
|
||||
const runtimeUser = session.messages.find(
|
||||
message => message.role === "user" && getTextContent(message) === "Preserved summary",
|
||||
);
|
||||
if (!runtimeUser || runtimeUser.role !== "user") {
|
||||
if (runtimeUser?.role !== "user") {
|
||||
throw new Error("Expected runtime user message");
|
||||
}
|
||||
expect(runtimeUser.providerPayload).toEqual(preservedUserPayload);
|
||||
@@ -458,7 +458,7 @@ describe("AgentSession OpenAI Responses replay boundaries", () => {
|
||||
const customEntry = snapshot.fileEntries.find(
|
||||
entry => entry.type === "custom_message" && entry.customType === "proxy-details",
|
||||
);
|
||||
if (!customEntry || customEntry.type !== "custom_message") {
|
||||
if (customEntry?.type !== "custom_message") {
|
||||
throw new Error("Expected captured custom message entry");
|
||||
}
|
||||
expect(customEntry.details).toEqual({ ok: true, nested: { value: "preserved" } });
|
||||
|
||||
@@ -16,7 +16,7 @@ type AutoRetryStartEvent = Extract<AgentSessionEvent, { type: "auto_retry_start"
|
||||
|
||||
function lastAssistant(session: AgentSession): AssistantMessage {
|
||||
const message = session.agent.state.messages.at(-1);
|
||||
if (!message || message.role !== "assistant") {
|
||||
if (message?.role !== "assistant") {
|
||||
throw new Error("Expected trailing assistant message");
|
||||
}
|
||||
return message as AssistantMessage;
|
||||
|
||||
@@ -33,7 +33,7 @@ function trackRetryEvents(session: AgentSession): {
|
||||
|
||||
function getLastAssistantMessage(session: AgentSession): AssistantMessage {
|
||||
const lastMessage = session.messages.at(-1);
|
||||
if (!lastMessage || lastMessage.role !== "assistant") {
|
||||
if (lastMessage?.role !== "assistant") {
|
||||
throw new Error("Expected final assistant message");
|
||||
}
|
||||
return lastMessage;
|
||||
|
||||
@@ -28,7 +28,7 @@ describe("generateFileMentionMessages path resolution", () => {
|
||||
const messages = await generateFileMentionMessages(["httpserap"], cwd);
|
||||
expect(messages).toHaveLength(1);
|
||||
const message = messages[0];
|
||||
if (!message || message.role !== "fileMention") {
|
||||
if (message?.role !== "fileMention") {
|
||||
throw new Error("expected file mention message");
|
||||
}
|
||||
expect(message.files).toHaveLength(1);
|
||||
@@ -44,7 +44,7 @@ describe("generateFileMentionMessages path resolution", () => {
|
||||
const messages = await generateFileMentionMessages(["docs/rea"], cwd);
|
||||
expect(messages).toHaveLength(1);
|
||||
const message = messages[0];
|
||||
if (!message || message.role !== "fileMention") {
|
||||
if (message?.role !== "fileMention") {
|
||||
throw new Error("expected file mention message");
|
||||
}
|
||||
expect(message.files[0]?.path).toBe("docs/readme.md");
|
||||
@@ -59,7 +59,7 @@ describe("generateFileMentionMessages path resolution", () => {
|
||||
const messages = await generateFileMentionMessages(["httpserap"], cwd);
|
||||
expect(messages).toHaveLength(1);
|
||||
const message = messages[0];
|
||||
if (!message || message.role !== "fileMention") {
|
||||
if (message?.role !== "fileMention") {
|
||||
throw new Error("expected file mention message");
|
||||
}
|
||||
expect(message.files[0]?.path).toBe("http_server_api_tests");
|
||||
|
||||
@@ -53,7 +53,7 @@ describe("RpcHostToolBridge", () => {
|
||||
|
||||
expect(frames).toHaveLength(1);
|
||||
const request = frames[0];
|
||||
if (!request || request.type !== "host_tool_call") {
|
||||
if (request?.type !== "host_tool_call") {
|
||||
throw new Error("Expected host_tool_call frame");
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ describe("RpcHostToolBridge", () => {
|
||||
const controller = new AbortController();
|
||||
const execution = tool.execute("toolu_2", {}, controller.signal);
|
||||
const request = frames[0];
|
||||
if (!request || request.type !== "host_tool_call") {
|
||||
if (request?.type !== "host_tool_call") {
|
||||
throw new Error("Expected host_tool_call frame");
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ describe("RpcHostUriBridge", () => {
|
||||
const pending = bridge.requestRead("db", parseInternalUrl("db://users/42"));
|
||||
expect(out.frames).toHaveLength(1);
|
||||
const request = out.frames[0];
|
||||
if (!request || request.type !== "host_uri_request") {
|
||||
if (request?.type !== "host_uri_request") {
|
||||
throw new Error("Expected host_uri_request frame");
|
||||
}
|
||||
expect(request.operation).toBe("read");
|
||||
@@ -71,7 +71,7 @@ describe("RpcHostUriBridge", () => {
|
||||
const pending = bridge.requestWrite("db", url, "new content");
|
||||
expect(out.frames).toHaveLength(1);
|
||||
const request = out.frames[0];
|
||||
if (!request || request.type !== "host_uri_request") {
|
||||
if (request?.type !== "host_uri_request") {
|
||||
throw new Error("Expected host_uri_request frame");
|
||||
}
|
||||
expect(request.operation).toBe("write");
|
||||
@@ -90,7 +90,7 @@ describe("RpcHostUriBridge", () => {
|
||||
const url = parseInternalUrl("db://users/42");
|
||||
const pending = bridge.requestRead("db", url);
|
||||
const request = out.frames[0];
|
||||
if (!request || request.type !== "host_uri_request") {
|
||||
if (request?.type !== "host_uri_request") {
|
||||
throw new Error("Expected host_uri_request frame");
|
||||
}
|
||||
bridge.handleResult({
|
||||
|
||||
@@ -20,7 +20,7 @@ const SKILL_TYPE = "skill-prompt";
|
||||
function readPersistedCustomMessageEntry<T>(session: SessionManager, id: string): CustomMessageEntry<T> {
|
||||
const branch = session.getBranch();
|
||||
const entry = branch.find(e => e.id === id);
|
||||
if (!entry || entry.type !== "custom_message") {
|
||||
if (entry?.type !== "custom_message") {
|
||||
throw new Error(`Expected custom_message entry with id ${id}, got ${entry?.type ?? "none"}`);
|
||||
}
|
||||
return entry as CustomMessageEntry<T>;
|
||||
|
||||
@@ -113,7 +113,7 @@ describe("SessionManager signature persistence", () => {
|
||||
const reloadedUserEntry = reloaded
|
||||
.getEntries()
|
||||
.find(entry => entry.type === "message" && entry.message.role === "user");
|
||||
if (!reloadedUserEntry || reloadedUserEntry.type !== "message" || reloadedUserEntry.message.role !== "user") {
|
||||
if (reloadedUserEntry?.type !== "message" || reloadedUserEntry.message.role !== "user") {
|
||||
throw new Error("Expected user message");
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ async function main() {
|
||||
const thinkingContent = fixtureMessage.content.find(c => c.type === "thinking");
|
||||
const textContent = fixtureMessage.content.find(c => c.type === "text");
|
||||
|
||||
if (!thinkingContent || thinkingContent.type !== "thinking") {
|
||||
if (thinkingContent?.type !== "thinking") {
|
||||
console.error("No thinking content in fixture");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ describe("EvalTool display() text surfacing", () => {
|
||||
|
||||
const image = result.content.find(c => c.type === "image");
|
||||
expect(image).toBeDefined();
|
||||
if (!image || image.type !== "image") throw new Error("Expected image content");
|
||||
if (image?.type !== "image") throw new Error("Expected image content");
|
||||
expect(image.data).not.toBe(base64);
|
||||
|
||||
const { width, height } = await new Bun.Image(Buffer.from(image.data, "base64")).metadata();
|
||||
|
||||
@@ -40,7 +40,7 @@ describe("TodoWriteTool auto-start behavior", () => {
|
||||
const tasks = result.details?.phases[0]?.tasks ?? [];
|
||||
expect(tasks.map(task => task.status)).toEqual(["in_progress", "pending"]);
|
||||
const summary = result.content.find(part => part.type === "text");
|
||||
if (!summary || summary.type !== "text") throw new Error("Expected text summary from todo_write");
|
||||
if (summary?.type !== "text") throw new Error("Expected text summary from todo_write");
|
||||
expect(summary.text).toContain("Remaining items (2):");
|
||||
expect(summary.text).toContain("status [in_progress] (Execution)");
|
||||
expect(summary.text).toContain("diagnostics [pending] (Execution)");
|
||||
@@ -62,13 +62,13 @@ describe("TodoWriteTool auto-start behavior", () => {
|
||||
const tasks = result.details?.phases[0]?.tasks ?? [];
|
||||
expect(tasks.map(task => task.status)).toEqual(["completed", "in_progress"]);
|
||||
const summary = result.content.find(part => part.type === "text");
|
||||
if (!summary || summary.type !== "text") throw new Error("Expected text summary from todo_write");
|
||||
if (summary?.type !== "text") throw new Error("Expected text summary from todo_write");
|
||||
expect(summary.text).toContain("Remaining items (1):");
|
||||
expect(summary.text).toContain("diagnostics [in_progress] (Execution)");
|
||||
|
||||
const completedResult = await tool.execute("call-3", { ops: [{ op: "done", task: "diagnostics" }] });
|
||||
const completedSummary = completedResult.content.find(part => part.type === "text");
|
||||
if (!completedSummary || completedSummary.type !== "text") {
|
||||
if (completedSummary?.type !== "text") {
|
||||
throw new Error("Expected text summary from todo_write");
|
||||
}
|
||||
expect(completedSummary.text).toContain("Remaining items: none.");
|
||||
@@ -189,7 +189,7 @@ describe("TodoWriteTool ops operations", () => {
|
||||
const result = await tool.execute("call-2", { ops: [{ op: "rm" }] });
|
||||
expect(result.details?.phases[0]?.tasks).toEqual([]);
|
||||
const summary = result.content.find(part => part.type === "text");
|
||||
if (!summary || summary.type !== "text") throw new Error("Expected text summary");
|
||||
if (summary?.type !== "text") throw new Error("Expected text summary");
|
||||
expect(summary.text).toContain("Todo list cleared.");
|
||||
});
|
||||
|
||||
|
||||
@@ -422,7 +422,7 @@ export async function getRequestDetails(id: number): Promise<RequestDetails | nu
|
||||
if (!msg) return null;
|
||||
|
||||
const entry = await getSessionEntry(msg.sessionFile, msg.entryId);
|
||||
if (!entry || entry.type !== "message") return null;
|
||||
if (entry?.type !== "message") return null;
|
||||
|
||||
// TODO: Get parent/context messages?
|
||||
// For now we return the single entry which contains the assistant response.
|
||||
|
||||
@@ -109,7 +109,7 @@ function extractStats(
|
||||
currentServiceTier: ServiceTier | undefined,
|
||||
): MessageStats | null {
|
||||
const msg = entry.message as AssistantMessage;
|
||||
if (!msg || msg.role !== "assistant") return null;
|
||||
if (msg?.role !== "assistant") return null;
|
||||
|
||||
// Backfill: when the session recorded `priority` as the active service tier
|
||||
// at this point but the AI usage payload was captured before priority
|
||||
|
||||
Reference in New Issue
Block a user