Add WORKER_SESSION_TYPE=opencode with a headless OpenCode session adapter, compose profile, and OmniRoute plugin config. Prefer OpenCode over the unused OpenHands agent-server path; fix missing yaml runtime dependency. Co-authored-by: Cursor <cursoragent@cursor.com>
93 lines
2.7 KiB
TypeScript
93 lines
2.7 KiB
TypeScript
import { describe, expect, it, vi } from "vitest";
|
|
|
|
import { createOpenCodeExecutor } from "./index.js";
|
|
|
|
describe("createOpenCodeExecutor", () => {
|
|
it("returns null when serverUrl is empty", () => {
|
|
const exec = createOpenCodeExecutor({
|
|
serverUrl: "",
|
|
serverPassword: "",
|
|
serverUsername: "opencode",
|
|
repoRoot: "/workspace/repo",
|
|
providerId: "omniroute",
|
|
});
|
|
expect(exec).toBeNull();
|
|
});
|
|
|
|
it("returns an opencode executor with the expected id", () => {
|
|
const exec = createOpenCodeExecutor({
|
|
serverUrl: "http://opencode:4096",
|
|
serverPassword: "secret",
|
|
serverUsername: "opencode",
|
|
repoRoot: "/workspace/repo",
|
|
providerId: "omniroute",
|
|
});
|
|
expect(exec).not.toBeNull();
|
|
expect(exec?.id).toBe("opencode");
|
|
});
|
|
|
|
it("creates a session and posts a message with basic auth", async () => {
|
|
const fetchImpl = vi
|
|
.fn()
|
|
.mockResolvedValueOnce(
|
|
new Response(JSON.stringify({ id: "ses_1" }), { status: 200 }),
|
|
)
|
|
.mockResolvedValueOnce(
|
|
new Response(
|
|
JSON.stringify({
|
|
info: { role: "assistant" },
|
|
parts: [{ type: "text", text: "done" }, { type: "tool", tool: "bash" }],
|
|
}),
|
|
{ status: 200 },
|
|
),
|
|
);
|
|
|
|
vi.stubGlobal("fetch", fetchImpl);
|
|
|
|
const exec = createOpenCodeExecutor({
|
|
serverUrl: "http://opencode:4096",
|
|
serverPassword: "secret",
|
|
serverUsername: "opencode",
|
|
repoRoot: "/workspace/repo",
|
|
providerId: "omniroute",
|
|
});
|
|
expect(exec).not.toBeNull();
|
|
if (!exec) return;
|
|
|
|
const result = await exec.run(
|
|
{
|
|
workspaceId: "w",
|
|
convoyId: "c",
|
|
roleId: "role-implementer",
|
|
briefId: "b",
|
|
repoRoot: "/workspace/repo",
|
|
},
|
|
{
|
|
resolvedModel: {
|
|
modelId: "omniroute/auto/coding",
|
|
providerType: "openai",
|
|
alias: "auto/coding",
|
|
},
|
|
resolvedAlias: "auto/coding",
|
|
rolePromptPath: "/tmp/role.md",
|
|
maxSteps: 5,
|
|
buildPrompt: () => "Implement the thing",
|
|
convoyTitle: "test",
|
|
},
|
|
);
|
|
|
|
expect(result.summary).toBe("done");
|
|
expect(result.toolCalls).toBe(1);
|
|
expect(fetchImpl).toHaveBeenCalledTimes(2);
|
|
const [, createInit] = fetchImpl.mock.calls[0]!;
|
|
expect((createInit as RequestInit).headers).toMatchObject({
|
|
Authorization: expect.stringMatching(/^Basic /),
|
|
});
|
|
const [msgUrl, msgInit] = fetchImpl.mock.calls[1]!;
|
|
expect(msgUrl).toBe("http://opencode:4096/session/ses_1/message");
|
|
const body = JSON.parse(String((msgInit as RequestInit).body));
|
|
expect(body.model).toEqual({ providerID: "omniroute", modelID: "auto/coding" });
|
|
|
|
vi.unstubAllGlobals();
|
|
});
|
|
});
|