Files
paseo/packages/cli/src/commands/agent/update.test.ts
T
Mohamed BoudraandGitHub 963d4f9240 Configure agent thinking from the CLI (#2533)
* feat(cli): update agent thinking from the CLI

* fix(cli): harden agent thinking updates

* feat(cli): configure thinking for schedules

* fix(cli): report applied thinking updates

* fix(cli): report current agent thinking state
2026-07-28 22:30:50 +08:00

109 lines
3.1 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { AgentProviderNotice } from "@getpaseo/protocol/agent-types";
import {
applyAgentChanges,
toAgentUpdateResult,
type AgentMetadataChanges,
type AgentUpdateClient,
} from "./update.js";
class RecordingAgentUpdateClient implements AgentUpdateClient {
readonly metadataUpdates: Array<{
agentId: string;
updates: AgentMetadataChanges;
}> = [];
readonly thinkingUpdates: Array<{ agentId: string; thinkingOptionId: string }> = [];
thinkingNotice: AgentProviderNotice | null = null;
constructor(private readonly supportsThinkingUpdate = true) {}
getLastServerInfoMessage() {
return { features: { agentThinkingUpdate: this.supportsThinkingUpdate } };
}
async updateAgent(agentId: string, updates: AgentMetadataChanges): Promise<void> {
this.metadataUpdates.push({ agentId, updates });
}
async setAgentThinkingOption(
agentId: string,
thinkingOptionId: string,
): Promise<AgentProviderNotice | null> {
this.thinkingUpdates.push({ agentId, thinkingOptionId });
return this.thinkingNotice;
}
}
describe("applyAgentChanges", () => {
it("updates an agent's thinking without issuing an empty metadata update", async () => {
const client = new RecordingAgentUpdateClient();
const result = await applyAgentChanges(client, "agent-1", {
type: "thinking",
thinkingOptionId: "high",
});
expect(client.metadataUpdates).toEqual([]);
expect(client.thinkingUpdates).toEqual([{ agentId: "agent-1", thinkingOptionId: "high" }]);
expect(result).toEqual({
notice: null,
});
});
it("requires a daemon that advertises thinking updates", async () => {
const client = new RecordingAgentUpdateClient(false);
await expect(
applyAgentChanges(client, "agent-1", { type: "thinking", thinkingOptionId: "high" }),
).rejects.toMatchObject({
code: "DAEMON_UPDATE_REQUIRED",
message: "Update the host to use agent thinking updates.",
});
expect(client.metadataUpdates).toEqual([]);
expect(client.thinkingUpdates).toEqual([]);
});
it("returns the provider notice from a thinking update", async () => {
const client = new RecordingAgentUpdateClient();
client.thinkingNotice = {
type: "warning",
message: "Thinking changes apply to the next turn.",
};
const notice = await applyAgentChanges(client, "agent-1", {
type: "thinking",
thinkingOptionId: "high",
});
expect(notice).toEqual({
notice: {
type: "warning",
message: "Thinking changes apply to the next turn.",
},
});
});
});
describe("toAgentUpdateResult", () => {
it("reports the current thinking option after a metadata update", () => {
const result = toAgentUpdateResult(
{
id: "agent-1",
title: "Renamed agent",
labels: { team: "platform" },
effectiveThinkingOptionId: "high",
},
{ notice: null },
);
expect(result).toEqual({
agentId: "agent-1",
name: "Renamed agent",
labels: "team=platform",
thinkingOptionId: "high",
noticeType: null,
notice: null,
});
});
});