feat(coding-agent): add fork position and duplicate session option (#3431)
This commit is contained in:
@@ -176,7 +176,7 @@ describe("AgentSessionRuntime session lifecycle events", () => {
|
||||
expect(successResult.selectedText).toBe("hello");
|
||||
await runtimeHost.session.bindExtensions({});
|
||||
expect(events).toEqual([
|
||||
{ type: "session_before_fork", entryId: userMessage.entryId },
|
||||
{ type: "session_before_fork", entryId: userMessage.entryId, position: "before" },
|
||||
{ type: "session_start", reason: "fork", previousSessionFile },
|
||||
]);
|
||||
|
||||
@@ -184,6 +184,12 @@ describe("AgentSessionRuntime session lifecycle events", () => {
|
||||
cancelNextFork = true;
|
||||
const cancelResult = await runtimeHost.fork(userMessage.entryId);
|
||||
expect(cancelResult).toEqual({ cancelled: true });
|
||||
expect(events).toEqual([{ type: "session_before_fork", entryId: userMessage.entryId }]);
|
||||
expect(events).toEqual([{ type: "session_before_fork", entryId: userMessage.entryId, position: "before" }]);
|
||||
|
||||
events.length = 0;
|
||||
cancelNextFork = true;
|
||||
const cancelAtResult = await runtimeHost.fork("missing-entry", { position: "at" });
|
||||
expect(cancelAtResult).toEqual({ cancelled: true });
|
||||
expect(events).toEqual([{ type: "session_before_fork", entryId: "missing-entry", position: "at" }]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -695,6 +695,30 @@ describe("ExtensionRunner", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("command context", () => {
|
||||
it("passes fork options through to the bound handler", async () => {
|
||||
const runtime = createExtensionRuntime();
|
||||
const runner = new ExtensionRunner([], runtime, tempDir, sessionManager, modelRegistry);
|
||||
const fork = vi.fn(async () => ({ cancelled: false }));
|
||||
|
||||
runner.bindCommandContext({
|
||||
waitForIdle: async () => {},
|
||||
newSession: async () => ({ cancelled: false }),
|
||||
fork,
|
||||
navigateTree: async () => ({ cancelled: false }),
|
||||
switchSession: async () => ({ cancelled: false }),
|
||||
reload: async () => {},
|
||||
});
|
||||
|
||||
const commandContext = runner.createCommandContext();
|
||||
await commandContext.fork("entry-1");
|
||||
expect(fork).toHaveBeenCalledWith("entry-1", undefined);
|
||||
|
||||
await commandContext.fork("entry-2", { position: "at" });
|
||||
expect(fork).toHaveBeenLastCalledWith("entry-2", { position: "at" });
|
||||
});
|
||||
});
|
||||
|
||||
describe("hasHandlers", () => {
|
||||
it("returns true when handlers exist for event type", async () => {
|
||||
const extCode = `
|
||||
|
||||
@@ -217,7 +217,7 @@ describe("AgentSessionRuntime characterization", () => {
|
||||
expect(successResult.selectedText).toBe("hello");
|
||||
await runtime.session.bindExtensions({});
|
||||
expect(events).toEqual([
|
||||
{ type: "session_before_fork", entryId: userMessage.entryId },
|
||||
{ type: "session_before_fork", entryId: userMessage.entryId, position: "before" },
|
||||
{ type: "session_start", reason: "fork", previousSessionFile },
|
||||
]);
|
||||
|
||||
@@ -225,7 +225,13 @@ describe("AgentSessionRuntime characterization", () => {
|
||||
cancelNextFork = true;
|
||||
const cancelResult = await runtime.fork(userMessage.entryId);
|
||||
expect(cancelResult).toEqual({ cancelled: true });
|
||||
expect(events).toEqual([{ type: "session_before_fork", entryId: userMessage.entryId }]);
|
||||
expect(events).toEqual([{ type: "session_before_fork", entryId: userMessage.entryId, position: "before" }]);
|
||||
|
||||
events.length = 0;
|
||||
cancelNextFork = true;
|
||||
const cancelAtResult = await runtime.fork("missing-entry", { position: "at" });
|
||||
expect(cancelAtResult).toEqual({ cancelled: true });
|
||||
expect(events).toEqual([{ type: "session_before_fork", entryId: "missing-entry", position: "at" }]);
|
||||
});
|
||||
|
||||
it("throws when forking with an invalid entry id", async () => {
|
||||
|
||||
Reference in New Issue
Block a user