Skip to content

Commit 11c33d5

Browse files
authored
test(server): cover REST API project skills (#26451)
1 parent 2a487ea commit 11c33d5

1 file changed

Lines changed: 63 additions & 0 deletions

File tree

packages/opencode/test/server/httpapi-sdk.test.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,13 +231,46 @@ function withFakeLlm<A, E, R>(backend: Backend, run: (input: LlmProjectFixture)
231231
}).pipe(Effect.provide(TestLLMServer.layer))
232232
}
233233

234+
function withFakeLlmProject<A, E, R>(
235+
backend: Backend,
236+
options: { setup?: (dir: string) => Effect.Effect<void> },
237+
run: (input: LlmProjectFixture) => Effect.Effect<A, E, R>,
238+
) {
239+
return Effect.gen(function* () {
240+
const llm = yield* TestLLMServer
241+
return yield* withProject(
242+
backend,
243+
{
244+
config: providerConfig(llm.url),
245+
setup: options.setup,
246+
},
247+
(input) => run({ ...input, llm }),
248+
)
249+
}).pipe(Effect.provide(TestLLMServer.layer))
250+
}
251+
234252
function writeStandardFiles(dir: string) {
235253
return Effect.all([
236254
call(() => Bun.write(path.join(dir, "hello.txt"), "hello")),
237255
call(() => Bun.write(path.join(dir, "needle.ts"), "export const needle = 'sdk-parity'\n")),
238256
]).pipe(Effect.asVoid)
239257
}
240258

259+
function writeProjectSkill(dir: string) {
260+
return call(() =>
261+
Bun.write(
262+
path.join(dir, ".opencode", "skills", "project-rest-skill", "SKILL.md"),
263+
`---
264+
name: project-rest-skill
265+
description: A project skill visible to REST API prompts.
266+
---
267+
268+
# Project REST Skill
269+
`,
270+
),
271+
).pipe(Effect.asVoid)
272+
}
273+
241274
function seedMessage(directory: string, sessionID: string) {
242275
const id = SessionID.make(sessionID)
243276
return call(
@@ -647,6 +680,36 @@ describe("HttpApi SDK", () => {
647680
),
648681
)
649682

683+
httpapi(
684+
"includes project skills in REST API async prompt context",
685+
withFakeLlmProject("httpapi", { setup: writeProjectSkill }, ({ sdk, llm }) =>
686+
Effect.gen(function* () {
687+
yield* llm.text("skill context ok", { usage: { input: 11, output: 7 } })
688+
const session = yield* capture(() =>
689+
sdk.session.create({
690+
title: "project skill prompt",
691+
permission: [{ permission: "*", pattern: "*", action: "allow" }],
692+
}),
693+
)
694+
const sessionID = String(record(session.data).id)
695+
const prompt = yield* capture(() =>
696+
sdk.session.promptAsync({
697+
sessionID,
698+
agent: "build",
699+
model: { providerID: "test", modelID: "test-model" },
700+
parts: [{ type: "text", text: "hello skill context" }],
701+
}),
702+
)
703+
yield* llm.wait(1)
704+
const inputs = yield* llm.inputs
705+
706+
expect(session.status).toBe(200)
707+
expect(prompt.status).toBe(204)
708+
expect(JSON.stringify(inputs[0])).toContain("project-rest-skill")
709+
}),
710+
),
711+
)
712+
650713
parity("matches generated SDK TUI validation and command routes across backends", (backend) =>
651714
withStandardProject(backend, ({ sdk }) =>
652715
Effect.gen(function* () {

0 commit comments

Comments
 (0)