Skip to content

Commit 348138c

Browse files
committed
Revise to use TS RunResult; Pass in API key
1 parent d8e31e5 commit 348138c

2 files changed

Lines changed: 80 additions & 8 deletions

File tree

scripts/eval_skills/agent.ts

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Agent } from "@cursor/sdk";
1+
import { Agent, type RunResult } from "@cursor/sdk";
22
import { validateAgentResult } from "./schema.js";
33
import type { AgentResult } from "./schema.js";
44

@@ -24,6 +24,11 @@ function substitute(template: string, vars: Record<string, string>): string {
2424
}
2525

2626
export async function runAgent(input: RunAgentInput): Promise<RunAgentOutput> {
27+
const apiKey = process.env.CURSOR_API_KEY;
28+
if (!apiKey) {
29+
return { ok: false, error: "CURSOR_API_KEY env var is not set" };
30+
}
31+
2732
const prompt = substitute(input.promptTemplate, {
2833
SKILL_PATH: input.skillPath,
2934
SKILL_CONTENT: input.skillContent,
@@ -32,22 +37,31 @@ export async function runAgent(input: RunAgentInput): Promise<RunAgentOutput> {
3237
RUBRIC: input.rubric,
3338
});
3439

35-
let raw: string;
40+
let res: RunResult;
3641
try {
37-
const res = await Agent.prompt(prompt, {
42+
res = await Agent.prompt(prompt, {
43+
apiKey,
44+
model: { id: "composer-2" },
3845
local: { cwd: process.cwd() },
3946
});
40-
if (!res.result) {
41-
return { ok: false, error: "agent returned no result" };
42-
}
43-
raw = res.result;
4447
} catch (err) {
4548
return {
4649
ok: false,
4750
error: err instanceof Error ? err.message : String(err),
4851
};
4952
}
5053

54+
if (res.status !== "finished") {
55+
return {
56+
ok: false,
57+
error: `agent run ended with status "${res.status}"`,
58+
};
59+
}
60+
if (!res.result) {
61+
return { ok: false, error: "agent returned no result" };
62+
}
63+
const raw = res.result;
64+
5165
let parsed: unknown;
5266
try {
5367
parsed = JSON.parse(raw);

tests/eval_skills/agent.test.ts

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, expect, it, vi } from "vitest";
1+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
22

33
vi.mock("@cursor/sdk", () => ({
44
Agent: {
@@ -14,6 +14,14 @@ vi.mock("@cursor/sdk", () => ({
1414
import { runAgent } from "../../scripts/eval_skills/agent.js";
1515

1616
describe("runAgent", () => {
17+
beforeEach(() => {
18+
vi.stubEnv("CURSOR_API_KEY", "test-key");
19+
});
20+
21+
afterEach(() => {
22+
vi.unstubAllEnvs();
23+
});
24+
1725
it("returns a validated AgentResult on a successful call", async () => {
1826
const r = await runAgent({
1927
skillPath: "skills/x/SKILL.md",
@@ -59,4 +67,54 @@ describe("runAgent", () => {
5967
expect(r.ok).toBe(false);
6068
if (!r.ok) expect(r.error).toContain("api down");
6169
});
70+
71+
it("returns ok:false when the run was cancelled", async () => {
72+
const sdk = await import("@cursor/sdk");
73+
vi.mocked(sdk.Agent.prompt).mockResolvedValueOnce({
74+
id: "run-3",
75+
status: "cancelled",
76+
});
77+
const r = await runAgent({
78+
skillPath: "skills/x/SKILL.md",
79+
skillContent: "x",
80+
siblingIndexJson: "[]",
81+
promptTemplate: "x",
82+
repoRulesExcerpt: "",
83+
rubric: "",
84+
});
85+
expect(r.ok).toBe(false);
86+
if (!r.ok) expect(r.error).toContain("cancelled");
87+
});
88+
89+
it("returns ok:false when the run errored", async () => {
90+
const sdk = await import("@cursor/sdk");
91+
vi.mocked(sdk.Agent.prompt).mockResolvedValueOnce({
92+
id: "run-4",
93+
status: "error",
94+
});
95+
const r = await runAgent({
96+
skillPath: "skills/x/SKILL.md",
97+
skillContent: "x",
98+
siblingIndexJson: "[]",
99+
promptTemplate: "x",
100+
repoRulesExcerpt: "",
101+
rubric: "",
102+
});
103+
expect(r.ok).toBe(false);
104+
if (!r.ok) expect(r.error).toContain("error");
105+
});
106+
107+
it("returns ok:false when CURSOR_API_KEY is not set", async () => {
108+
vi.stubEnv("CURSOR_API_KEY", "");
109+
const r = await runAgent({
110+
skillPath: "skills/x/SKILL.md",
111+
skillContent: "x",
112+
siblingIndexJson: "[]",
113+
promptTemplate: "x",
114+
repoRulesExcerpt: "",
115+
rubric: "",
116+
});
117+
expect(r.ok).toBe(false);
118+
if (!r.ok) expect(r.error).toContain("CURSOR_API_KEY");
119+
});
62120
});

0 commit comments

Comments
 (0)