feat: handle opencode permission requests
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
import { describe, expect, it } from "bun:test";
|
||||
|
||||
import {
|
||||
streamPromptResponse,
|
||||
type PermissionRequestPayload,
|
||||
} from "../../src/routes/chatStream.js";
|
||||
import { type OpencodeRuntimeAdapter } from "../../src/runtime/opencode.js";
|
||||
|
||||
const createEventStream = (events: unknown[]) => ({
|
||||
async *[Symbol.asyncIterator]() {
|
||||
for (const event of events) {
|
||||
yield event;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
describe("streamPromptResponse", () => {
|
||||
it("forwards opencode permission requests as SSE payloads", async () => {
|
||||
const runtime = {
|
||||
subscribeEvents: async () =>
|
||||
createEventStream([
|
||||
{
|
||||
type: "permission.asked",
|
||||
properties: {
|
||||
id: "perm-1",
|
||||
sessionID: "runtime-session-1",
|
||||
permission: "bash",
|
||||
patterns: ["rm *"],
|
||||
metadata: { command: "rm tmp.txt" },
|
||||
always: ["rm *"],
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "session.idle",
|
||||
properties: {
|
||||
sessionID: "runtime-session-1",
|
||||
},
|
||||
},
|
||||
]),
|
||||
prompt: async () => undefined,
|
||||
messages: async () => [],
|
||||
} as unknown as OpencodeRuntimeAdapter;
|
||||
const events: Array<{ event: string; data: Record<string, unknown> }> = [];
|
||||
|
||||
await streamPromptResponse({
|
||||
runtime,
|
||||
sessionId: "runtime-session-1",
|
||||
clientSessionId: "client-session-1",
|
||||
message: "delete temp",
|
||||
write: (event, data) => events.push({ event, data }),
|
||||
});
|
||||
|
||||
const permissionEvent = events.find((item) => item.event === "permission_request");
|
||||
expect(permissionEvent?.data).toMatchObject({
|
||||
session_id: "client-session-1",
|
||||
request_id: "perm-1",
|
||||
permission: "bash",
|
||||
patterns: ["rm *"],
|
||||
metadata: { command: "rm tmp.txt" },
|
||||
always: ["rm *"],
|
||||
} satisfies Partial<PermissionRequestPayload>);
|
||||
});
|
||||
|
||||
it("forwards opencode v2 permission requests as SSE payloads", async () => {
|
||||
const runtime = {
|
||||
subscribeEvents: async () =>
|
||||
createEventStream([
|
||||
{
|
||||
type: "permission.v2.asked",
|
||||
properties: {
|
||||
id: "perm-v2-1",
|
||||
sessionID: "runtime-session-1",
|
||||
action: "external_directory",
|
||||
resources: ["/tmp"],
|
||||
save: ["/tmp"],
|
||||
metadata: { path: "/tmp" },
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "session.idle",
|
||||
properties: {
|
||||
sessionID: "runtime-session-1",
|
||||
},
|
||||
},
|
||||
]),
|
||||
prompt: async () => undefined,
|
||||
messages: async () => [],
|
||||
} as unknown as OpencodeRuntimeAdapter;
|
||||
const events: Array<{ event: string; data: Record<string, unknown> }> = [];
|
||||
|
||||
await streamPromptResponse({
|
||||
runtime,
|
||||
sessionId: "runtime-session-1",
|
||||
clientSessionId: "client-session-1",
|
||||
message: "read /tmp",
|
||||
write: (event, data) => events.push({ event, data }),
|
||||
});
|
||||
|
||||
const permissionEvent = events.find((item) => item.event === "permission_request");
|
||||
expect(permissionEvent?.data).toMatchObject({
|
||||
session_id: "client-session-1",
|
||||
request_id: "perm-v2-1",
|
||||
permission: "external_directory",
|
||||
patterns: ["/tmp"],
|
||||
metadata: { path: "/tmp" },
|
||||
always: ["/tmp"],
|
||||
} satisfies Partial<PermissionRequestPayload>);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user