feat: default new Codex agents to the qualified Paperclip Runner

Resolve creation intent across onboarding, hires, imports, and the UI. Preserve existing execution and qualify automatic defaults for shipped Linux x64 artifacts.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-10-09 10:12:15 -05:00
1 parent 835a022936
commit aa879604ae
91 files changed
+2718 -884

No files matched your search

+12
View File
@@ -70,6 +70,18 @@ describe("agent lifecycle commands", () => {
]);
});
it("sends automatic selection when omitted and supports explicit runner overrides", async () => {
const fetchMock = vi.fn().mockImplementation(() => Promise.resolve(jsonResponse()));
vi.stubGlobal("fetch", fetchMock);
const payload = { name: "Builder", adapterType: "codex_local" };
await run(["agent", "create", "--company-id", COMPANY_ID, "--payload-json", JSON.stringify(payload)]);
await run(["agent", "create", "--company-id", COMPANY_ID, "--payload-json", JSON.stringify({ ...payload, runner: "auto" }), "--runner", "legacy"]);
await run(["agent", "hire", "--company-id", COMPANY_ID, "--payload-json", JSON.stringify(payload), "--runner", "paperclip"]);
expect(JSON.parse(fetchMock.mock.calls[0]![1].body).runner).toBeUndefined();
expect(JSON.parse(fetchMock.mock.calls[1]![1].body).runner).toBe("legacy");
expect(JSON.parse(fetchMock.mock.calls[2]![1].body).runner).toBe("paperclip");
});
it("wraps configuration, runtime, skills, and instructions endpoints", async () => {
const fetchMock = vi.fn().mockImplementation(() => Promise.resolve(jsonResponse()));
vi.stubGlobal("fetch", fetchMock);
+5 -2
View File
@@ -57,6 +57,7 @@ interface AgentWakeOptions extends BaseClientOptions {
}
interface AgentJsonPayloadOptions extends BaseClientOptions {
runner?: "auto" | "paperclip" | "legacy";
companyId?: string;
payloadJson: string;
}
@@ -348,10 +349,11 @@ export function registerAgentCommands(program: Command): void {
.description("Create an agent from a JSON payload")
.option("-C, --company-id <id>", "Company ID")
.requiredOption("--payload-json <json>", "CreateAgent JSON payload")
.option("--runner <runner>", "Runner: auto (default), paperclip, or legacy")
.action(async (opts: AgentJsonPayloadOptions) => {
try {
const ctx = resolveCommandContext(opts, { requireCompany: true });
const payload = createAgentSchema.parse(parseJson(opts.payloadJson));
const payload = createAgentSchema.parse({ ...parseJsonObject(opts.payloadJson), ...(opts.runner ? { runner: opts.runner } : {}) });
const created = await ctx.api.post<Agent>(apiPath`/api/companies/${ctx.companyId}/agents`, payload);
printOutput(created, { json: ctx.json });
} catch (err) {
@@ -367,10 +369,11 @@ export function registerAgentCommands(program: Command): void {
.description("Create an agent hire request")
.option("-C, --company-id <id>", "Company ID")
.requiredOption("--payload-json <json>", "CreateAgentHire JSON payload")
.option("--runner <runner>", "Runner: auto (default), paperclip, or legacy")
.action(async (opts: AgentJsonPayloadOptions) => {
try {
const ctx = resolveCommandContext(opts, { requireCompany: true });
const result = await ctx.api.post(apiPath`/api/companies/${ctx.companyId}/agent-hires`, parseJson(opts.payloadJson));
const result = await ctx.api.post(apiPath`/api/companies/${ctx.companyId}/agent-hires`, { ...parseJsonObject(opts.payloadJson), ...(opts.runner ? { runner: opts.runner } : {}) });
printOutput(result, { json: ctx.json });
} catch (err) {
handleCommandError(err);