test: add promptAsync mocks to all test files for promptAsync migration
This commit is contained in:
parent
fa77be0daf
commit
414cecd7df
@ -171,6 +171,7 @@ function createBackgroundManager(): BackgroundManager {
|
|||||||
const client = {
|
const client = {
|
||||||
session: {
|
session: {
|
||||||
prompt: async () => ({}),
|
prompt: async () => ({}),
|
||||||
|
promptAsync: async () => ({}),
|
||||||
abort: async () => ({}),
|
abort: async () => ({}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -880,12 +881,14 @@ describe("BackgroundManager.notifyParentSession - aborted parent", () => {
|
|||||||
test("should skip notification when parent session is aborted", async () => {
|
test("should skip notification when parent session is aborted", async () => {
|
||||||
//#given
|
//#given
|
||||||
let promptCalled = false
|
let promptCalled = false
|
||||||
|
const promptMock = async () => {
|
||||||
|
promptCalled = true
|
||||||
|
return {}
|
||||||
|
}
|
||||||
const client = {
|
const client = {
|
||||||
session: {
|
session: {
|
||||||
prompt: async () => {
|
prompt: promptMock,
|
||||||
promptCalled = true
|
promptAsync: promptMock,
|
||||||
return {}
|
|
||||||
},
|
|
||||||
abort: async () => ({}),
|
abort: async () => ({}),
|
||||||
messages: async () => {
|
messages: async () => {
|
||||||
const error = new Error("User aborted")
|
const error = new Error("User aborted")
|
||||||
@ -922,14 +925,16 @@ describe("BackgroundManager.notifyParentSession - aborted parent", () => {
|
|||||||
test("should swallow aborted error from prompt", async () => {
|
test("should swallow aborted error from prompt", async () => {
|
||||||
//#given
|
//#given
|
||||||
let promptCalled = false
|
let promptCalled = false
|
||||||
|
const promptMock = async () => {
|
||||||
|
promptCalled = true
|
||||||
|
const error = new Error("User aborted")
|
||||||
|
error.name = "MessageAbortedError"
|
||||||
|
throw error
|
||||||
|
}
|
||||||
const client = {
|
const client = {
|
||||||
session: {
|
session: {
|
||||||
prompt: async () => {
|
prompt: promptMock,
|
||||||
promptCalled = true
|
promptAsync: promptMock,
|
||||||
const error = new Error("User aborted")
|
|
||||||
error.name = "MessageAbortedError"
|
|
||||||
throw error
|
|
||||||
},
|
|
||||||
abort: async () => ({}),
|
abort: async () => ({}),
|
||||||
messages: async () => ({ data: [] }),
|
messages: async () => ({ data: [] }),
|
||||||
},
|
},
|
||||||
@ -1054,19 +1059,20 @@ describe("BackgroundManager.tryCompleteTask", () => {
|
|||||||
expect(concurrencyManager.getCount(concurrencyKey)).toBe(0)
|
expect(concurrencyManager.getCount(concurrencyKey)).toBe(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
test("should abort session on completion", async () => {
|
test("should abort session on completion", async () => {
|
||||||
// #given
|
// #given
|
||||||
const abortedSessionIDs: string[] = []
|
const abortedSessionIDs: string[] = []
|
||||||
const client = {
|
const client = {
|
||||||
session: {
|
session: {
|
||||||
prompt: async () => ({}),
|
prompt: async () => ({}),
|
||||||
abort: async (args: { path: { id: string } }) => {
|
promptAsync: async () => ({}),
|
||||||
abortedSessionIDs.push(args.path.id)
|
abort: async (args: { path: { id: string } }) => {
|
||||||
return {}
|
abortedSessionIDs.push(args.path.id)
|
||||||
},
|
return {}
|
||||||
messages: async () => ({ data: [] }),
|
},
|
||||||
},
|
messages: async () => ({ data: [] }),
|
||||||
}
|
},
|
||||||
|
}
|
||||||
manager.shutdown()
|
manager.shutdown()
|
||||||
manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput)
|
manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput)
|
||||||
stubNotifyParentSession(manager)
|
stubNotifyParentSession(manager)
|
||||||
@ -1196,24 +1202,26 @@ describe("BackgroundManager.resume concurrency key", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe("BackgroundManager.resume model persistence", () => {
|
describe("BackgroundManager.resume model persistence", () => {
|
||||||
let manager: BackgroundManager
|
let manager: BackgroundManager
|
||||||
let promptCalls: Array<{ path: { id: string }; body: Record<string, unknown> }>
|
let promptCalls: Array<{ path: { id: string }; body: Record<string, unknown> }>
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// given
|
// given
|
||||||
promptCalls = []
|
promptCalls = []
|
||||||
const client = {
|
const promptMock = async (args: { path: { id: string }; body: Record<string, unknown> }) => {
|
||||||
session: {
|
promptCalls.push(args)
|
||||||
prompt: async (args: { path: { id: string }; body: Record<string, unknown> }) => {
|
return {}
|
||||||
promptCalls.push(args)
|
}
|
||||||
return {}
|
const client = {
|
||||||
},
|
session: {
|
||||||
abort: async () => ({}),
|
prompt: promptMock,
|
||||||
},
|
promptAsync: promptMock,
|
||||||
}
|
abort: async () => ({}),
|
||||||
manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput)
|
},
|
||||||
stubNotifyParentSession(manager)
|
}
|
||||||
})
|
manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput)
|
||||||
|
stubNotifyParentSession(manager)
|
||||||
|
})
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
manager.shutdown()
|
manager.shutdown()
|
||||||
@ -1311,19 +1319,20 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => {
|
|||||||
let manager: BackgroundManager
|
let manager: BackgroundManager
|
||||||
let mockClient: ReturnType<typeof createMockClient>
|
let mockClient: ReturnType<typeof createMockClient>
|
||||||
|
|
||||||
function createMockClient() {
|
function createMockClient() {
|
||||||
return {
|
return {
|
||||||
session: {
|
session: {
|
||||||
create: async () => ({ data: { id: `ses_${crypto.randomUUID()}` } }),
|
create: async () => ({ data: { id: `ses_${crypto.randomUUID()}` } }),
|
||||||
get: async () => ({ data: { directory: "/test/dir" } }),
|
get: async () => ({ data: { directory: "/test/dir" } }),
|
||||||
prompt: async () => ({}),
|
prompt: async () => ({}),
|
||||||
messages: async () => ({ data: [] }),
|
promptAsync: async () => ({}),
|
||||||
todo: async () => ({ data: [] }),
|
messages: async () => ({ data: [] }),
|
||||||
status: async () => ({ data: {} }),
|
todo: async () => ({ data: [] }),
|
||||||
abort: async () => ({}),
|
status: async () => ({ data: {} }),
|
||||||
},
|
abort: async () => ({}),
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// given
|
// given
|
||||||
@ -1871,13 +1880,14 @@ describe("BackgroundManager - Non-blocking Queue Integration", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe("BackgroundManager.checkAndInterruptStaleTasks", () => {
|
describe("BackgroundManager.checkAndInterruptStaleTasks", () => {
|
||||||
test("should NOT interrupt task running less than 30 seconds (min runtime guard)", async () => {
|
test("should NOT interrupt task running less than 30 seconds (min runtime guard)", async () => {
|
||||||
const client = {
|
const client = {
|
||||||
session: {
|
session: {
|
||||||
prompt: async () => ({}),
|
prompt: async () => ({}),
|
||||||
abort: async () => ({}),
|
promptAsync: async () => ({}),
|
||||||
},
|
abort: async () => ({}),
|
||||||
}
|
},
|
||||||
|
}
|
||||||
const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput, { staleTimeoutMs: 180_000 })
|
const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput, { staleTimeoutMs: 180_000 })
|
||||||
|
|
||||||
const task: BackgroundTask = {
|
const task: BackgroundTask = {
|
||||||
@ -1903,12 +1913,13 @@ describe("BackgroundManager.checkAndInterruptStaleTasks", () => {
|
|||||||
expect(task.status).toBe("running")
|
expect(task.status).toBe("running")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("should NOT interrupt task with recent lastUpdate", async () => {
|
test("should NOT interrupt task with recent lastUpdate", async () => {
|
||||||
const client = {
|
const client = {
|
||||||
session: {
|
session: {
|
||||||
prompt: async () => ({}),
|
prompt: async () => ({}),
|
||||||
abort: async () => ({}),
|
promptAsync: async () => ({}),
|
||||||
},
|
abort: async () => ({}),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput, { staleTimeoutMs: 180_000 })
|
const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput, { staleTimeoutMs: 180_000 })
|
||||||
|
|
||||||
@ -1935,11 +1946,12 @@ describe("BackgroundManager.checkAndInterruptStaleTasks", () => {
|
|||||||
expect(task.status).toBe("running")
|
expect(task.status).toBe("running")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("should interrupt task with stale lastUpdate (> 3min)", async () => {
|
test("should interrupt task with stale lastUpdate (> 3min)", async () => {
|
||||||
const client = {
|
const client = {
|
||||||
session: {
|
session: {
|
||||||
prompt: async () => ({}),
|
prompt: async () => ({}),
|
||||||
abort: async () => ({}),
|
promptAsync: async () => ({}),
|
||||||
|
abort: async () => ({}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput, { staleTimeoutMs: 180_000 })
|
const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput, { staleTimeoutMs: 180_000 })
|
||||||
@ -1971,10 +1983,11 @@ describe("BackgroundManager.checkAndInterruptStaleTasks", () => {
|
|||||||
expect(task.completedAt).toBeDefined()
|
expect(task.completedAt).toBeDefined()
|
||||||
})
|
})
|
||||||
|
|
||||||
test("should respect custom staleTimeoutMs config", async () => {
|
test("should respect custom staleTimeoutMs config", async () => {
|
||||||
const client = {
|
const client = {
|
||||||
session: {
|
session: {
|
||||||
prompt: async () => ({}),
|
prompt: async () => ({}),
|
||||||
|
promptAsync: async () => ({}),
|
||||||
abort: async () => ({}),
|
abort: async () => ({}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -2005,13 +2018,14 @@ describe("BackgroundManager.checkAndInterruptStaleTasks", () => {
|
|||||||
expect(task.error).toContain("Stale timeout")
|
expect(task.error).toContain("Stale timeout")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("should release concurrency before abort", async () => {
|
test("should release concurrency before abort", async () => {
|
||||||
const client = {
|
const client = {
|
||||||
session: {
|
session: {
|
||||||
prompt: async () => ({}),
|
prompt: async () => ({}),
|
||||||
abort: async () => ({}),
|
promptAsync: async () => ({}),
|
||||||
},
|
abort: async () => ({}),
|
||||||
}
|
},
|
||||||
|
}
|
||||||
const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput, { staleTimeoutMs: 180_000 })
|
const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput, { staleTimeoutMs: 180_000 })
|
||||||
stubNotifyParentSession(manager)
|
stubNotifyParentSession(manager)
|
||||||
|
|
||||||
@ -2040,13 +2054,14 @@ describe("BackgroundManager.checkAndInterruptStaleTasks", () => {
|
|||||||
expect(task.status).toBe("cancelled")
|
expect(task.status).toBe("cancelled")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("should handle multiple stale tasks in same poll cycle", async () => {
|
test("should handle multiple stale tasks in same poll cycle", async () => {
|
||||||
const client = {
|
const client = {
|
||||||
session: {
|
session: {
|
||||||
prompt: async () => ({}),
|
prompt: async () => ({}),
|
||||||
abort: async () => ({}),
|
promptAsync: async () => ({}),
|
||||||
},
|
abort: async () => ({}),
|
||||||
}
|
},
|
||||||
|
}
|
||||||
const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput, { staleTimeoutMs: 180_000 })
|
const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput, { staleTimeoutMs: 180_000 })
|
||||||
stubNotifyParentSession(manager)
|
stubNotifyParentSession(manager)
|
||||||
|
|
||||||
@ -2091,13 +2106,14 @@ describe("BackgroundManager.checkAndInterruptStaleTasks", () => {
|
|||||||
expect(task2.status).toBe("cancelled")
|
expect(task2.status).toBe("cancelled")
|
||||||
})
|
})
|
||||||
|
|
||||||
test("should use default timeout when config not provided", async () => {
|
test("should use default timeout when config not provided", async () => {
|
||||||
const client = {
|
const client = {
|
||||||
session: {
|
session: {
|
||||||
prompt: async () => ({}),
|
prompt: async () => ({}),
|
||||||
abort: async () => ({}),
|
promptAsync: async () => ({}),
|
||||||
},
|
abort: async () => ({}),
|
||||||
}
|
},
|
||||||
|
}
|
||||||
const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput)
|
const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput)
|
||||||
stubNotifyParentSession(manager)
|
stubNotifyParentSession(manager)
|
||||||
|
|
||||||
@ -2126,18 +2142,19 @@ describe("BackgroundManager.checkAndInterruptStaleTasks", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe("BackgroundManager.shutdown session abort", () => {
|
describe("BackgroundManager.shutdown session abort", () => {
|
||||||
test("should call session.abort for all running tasks during shutdown", () => {
|
test("should call session.abort for all running tasks during shutdown", () => {
|
||||||
// given
|
// given
|
||||||
const abortedSessionIDs: string[] = []
|
const abortedSessionIDs: string[] = []
|
||||||
const client = {
|
const client = {
|
||||||
session: {
|
session: {
|
||||||
prompt: async () => ({}),
|
prompt: async () => ({}),
|
||||||
abort: async (args: { path: { id: string } }) => {
|
promptAsync: async () => ({}),
|
||||||
abortedSessionIDs.push(args.path.id)
|
abort: async (args: { path: { id: string } }) => {
|
||||||
return {}
|
abortedSessionIDs.push(args.path.id)
|
||||||
},
|
return {}
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
|
}
|
||||||
const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput)
|
const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput)
|
||||||
|
|
||||||
const task1: BackgroundTask = {
|
const task1: BackgroundTask = {
|
||||||
@ -2175,18 +2192,19 @@ describe("BackgroundManager.shutdown session abort", () => {
|
|||||||
expect(abortedSessionIDs).toHaveLength(2)
|
expect(abortedSessionIDs).toHaveLength(2)
|
||||||
})
|
})
|
||||||
|
|
||||||
test("should not call session.abort for completed or cancelled tasks", () => {
|
test("should not call session.abort for completed or cancelled tasks", () => {
|
||||||
// given
|
// given
|
||||||
const abortedSessionIDs: string[] = []
|
const abortedSessionIDs: string[] = []
|
||||||
const client = {
|
const client = {
|
||||||
session: {
|
session: {
|
||||||
prompt: async () => ({}),
|
prompt: async () => ({}),
|
||||||
abort: async (args: { path: { id: string } }) => {
|
promptAsync: async () => ({}),
|
||||||
abortedSessionIDs.push(args.path.id)
|
abort: async (args: { path: { id: string } }) => {
|
||||||
return {}
|
abortedSessionIDs.push(args.path.id)
|
||||||
},
|
return {}
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
|
}
|
||||||
const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput)
|
const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput)
|
||||||
|
|
||||||
const completedTask: BackgroundTask = {
|
const completedTask: BackgroundTask = {
|
||||||
@ -2235,15 +2253,16 @@ describe("BackgroundManager.shutdown session abort", () => {
|
|||||||
expect(abortedSessionIDs).toHaveLength(0)
|
expect(abortedSessionIDs).toHaveLength(0)
|
||||||
})
|
})
|
||||||
|
|
||||||
test("should call onShutdown callback during shutdown", () => {
|
test("should call onShutdown callback during shutdown", () => {
|
||||||
// given
|
// given
|
||||||
let shutdownCalled = false
|
let shutdownCalled = false
|
||||||
const client = {
|
const client = {
|
||||||
session: {
|
session: {
|
||||||
prompt: async () => ({}),
|
prompt: async () => ({}),
|
||||||
abort: async () => ({}),
|
promptAsync: async () => ({}),
|
||||||
},
|
abort: async () => ({}),
|
||||||
}
|
},
|
||||||
|
}
|
||||||
const manager = new BackgroundManager(
|
const manager = new BackgroundManager(
|
||||||
{ client, directory: tmpdir() } as unknown as PluginInput,
|
{ client, directory: tmpdir() } as unknown as PluginInput,
|
||||||
undefined,
|
undefined,
|
||||||
@ -2261,14 +2280,15 @@ describe("BackgroundManager.shutdown session abort", () => {
|
|||||||
expect(shutdownCalled).toBe(true)
|
expect(shutdownCalled).toBe(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
test("should not throw when onShutdown callback throws", () => {
|
test("should not throw when onShutdown callback throws", () => {
|
||||||
// given
|
// given
|
||||||
const client = {
|
const client = {
|
||||||
session: {
|
session: {
|
||||||
prompt: async () => ({}),
|
prompt: async () => ({}),
|
||||||
abort: async () => ({}),
|
promptAsync: async () => ({}),
|
||||||
},
|
abort: async () => ({}),
|
||||||
}
|
},
|
||||||
|
}
|
||||||
const manager = new BackgroundManager(
|
const manager = new BackgroundManager(
|
||||||
{ client, directory: tmpdir() } as unknown as PluginInput,
|
{ client, directory: tmpdir() } as unknown as PluginInput,
|
||||||
undefined,
|
undefined,
|
||||||
@ -2509,19 +2529,20 @@ describe("BackgroundManager.handleEvent - early session.idle deferral", () => {
|
|||||||
const realDateNow = Date.now
|
const realDateNow = Date.now
|
||||||
const baseNow = realDateNow()
|
const baseNow = realDateNow()
|
||||||
|
|
||||||
const client = {
|
const client = {
|
||||||
session: {
|
session: {
|
||||||
prompt: async () => ({}),
|
prompt: async () => ({}),
|
||||||
abort: async () => ({}),
|
promptAsync: async () => ({}),
|
||||||
messages: async (args: { path: { id: string } }) => {
|
abort: async () => ({}),
|
||||||
messagesCalls.push(args.path.id)
|
messages: async (args: { path: { id: string } }) => {
|
||||||
return {
|
messagesCalls.push(args.path.id)
|
||||||
data: [
|
return {
|
||||||
{
|
data: [
|
||||||
info: { role: "assistant" },
|
{
|
||||||
parts: [{ type: "text", text: "ok" }],
|
info: { role: "assistant" },
|
||||||
},
|
parts: [{ type: "text", text: "ok" }],
|
||||||
],
|
},
|
||||||
|
],
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
todo: async () => ({ data: [] }),
|
todo: async () => ({ data: [] }),
|
||||||
@ -2566,23 +2587,24 @@ describe("BackgroundManager.handleEvent - early session.idle deferral", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
test("should not defer when session.idle fires after MIN_IDLE_TIME_MS", async () => {
|
test("should not defer when session.idle fires after MIN_IDLE_TIME_MS", async () => {
|
||||||
//#given - a running task started more than MIN_IDLE_TIME_MS ago
|
//#given - a running task started more than MIN_IDLE_TIME_MS ago
|
||||||
const sessionID = "session-late-idle"
|
const sessionID = "session-late-idle"
|
||||||
const client = {
|
const client = {
|
||||||
session: {
|
session: {
|
||||||
prompt: async () => ({}),
|
prompt: async () => ({}),
|
||||||
abort: async () => ({}),
|
promptAsync: async () => ({}),
|
||||||
messages: async () => ({
|
abort: async () => ({}),
|
||||||
data: [
|
messages: async () => ({
|
||||||
{
|
data: [
|
||||||
info: { role: "assistant" },
|
{
|
||||||
parts: [{ type: "text", text: "ok" }],
|
info: { role: "assistant" },
|
||||||
},
|
parts: [{ type: "text", text: "ok" }],
|
||||||
],
|
},
|
||||||
}),
|
],
|
||||||
todo: async () => ({ data: [] }),
|
}),
|
||||||
},
|
todo: async () => ({ data: [] }),
|
||||||
}
|
},
|
||||||
|
}
|
||||||
|
|
||||||
const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput)
|
const manager = new BackgroundManager({ client, directory: tmpdir() } as unknown as PluginInput)
|
||||||
stubNotifyParentSession(manager)
|
stubNotifyParentSession(manager)
|
||||||
@ -2618,20 +2640,21 @@ describe("BackgroundManager.handleEvent - early session.idle deferral", () => {
|
|||||||
const realDateNow = Date.now
|
const realDateNow = Date.now
|
||||||
const baseNow = realDateNow()
|
const baseNow = realDateNow()
|
||||||
|
|
||||||
const client = {
|
const client = {
|
||||||
session: {
|
session: {
|
||||||
prompt: async () => ({}),
|
prompt: async () => ({}),
|
||||||
abort: async () => ({}),
|
promptAsync: async () => ({}),
|
||||||
messages: async () => {
|
abort: async () => ({}),
|
||||||
messagesCallCount += 1
|
messages: async () => {
|
||||||
return {
|
messagesCallCount += 1
|
||||||
data: [
|
return {
|
||||||
{
|
data: [
|
||||||
info: { role: "assistant" },
|
{
|
||||||
parts: [{ type: "text", text: "ok" }],
|
info: { role: "assistant" },
|
||||||
},
|
parts: [{ type: "text", text: "ok" }],
|
||||||
],
|
},
|
||||||
}
|
],
|
||||||
|
}
|
||||||
},
|
},
|
||||||
todo: async () => ({ data: [] }),
|
todo: async () => ({ data: [] }),
|
||||||
},
|
},
|
||||||
|
|||||||
@ -34,6 +34,7 @@ describe("atlas hook", () => {
|
|||||||
client: {
|
client: {
|
||||||
session: {
|
session: {
|
||||||
prompt: promptMock,
|
prompt: promptMock,
|
||||||
|
promptAsync: promptMock,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
_promptMock: promptMock,
|
_promptMock: promptMock,
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -111,17 +111,19 @@ describe("look-at tool", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe("createLookAt error handling", () => {
|
describe("createLookAt error handling", () => {
|
||||||
// given JSON parse error occurs in session.prompt
|
// given JSON parse error occurs in session.promptAsync
|
||||||
// when LookAt tool executed
|
// when LookAt tool executed
|
||||||
// then return user-friendly error message
|
// then error propagates (band-aid removed since root cause fixed by promptAsync migration)
|
||||||
test("handles JSON parse error from session.prompt gracefully", async () => {
|
test("propagates JSON parse error from session.promptAsync", async () => {
|
||||||
|
const throwingMock = async () => {
|
||||||
|
throw new Error("JSON Parse error: Unexpected EOF")
|
||||||
|
}
|
||||||
const mockClient = {
|
const mockClient = {
|
||||||
session: {
|
session: {
|
||||||
get: async () => ({ data: { directory: "/project" } }),
|
get: async () => ({ data: { directory: "/project" } }),
|
||||||
create: async () => ({ data: { id: "ses_test_json_error" } }),
|
create: async () => ({ data: { id: "ses_test_json_error" } }),
|
||||||
prompt: async () => {
|
prompt: throwingMock,
|
||||||
throw new Error("JSON Parse error: Unexpected EOF")
|
promptAsync: throwingMock,
|
||||||
},
|
|
||||||
messages: async () => ({ data: [] }),
|
messages: async () => ({ data: [] }),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -142,28 +144,24 @@ describe("look-at tool", () => {
|
|||||||
ask: async () => {},
|
ask: async () => {},
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await tool.execute(
|
await expect(
|
||||||
{ file_path: "/test/file.png", goal: "analyze image" },
|
tool.execute({ file_path: "/test/file.png", goal: "analyze image" }, toolContext)
|
||||||
toolContext
|
).rejects.toThrow("JSON Parse error: Unexpected EOF")
|
||||||
)
|
|
||||||
|
|
||||||
expect(result).toContain("Error: Failed to analyze")
|
|
||||||
expect(result).toContain("malformed response")
|
|
||||||
expect(result).toContain("multimodal-looker")
|
|
||||||
expect(result).toContain("image/png")
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// given generic error occurs in session.prompt
|
// given generic error occurs in session.promptAsync
|
||||||
// when LookAt tool executed
|
// when LookAt tool executed
|
||||||
// then return error including original error message
|
// then error propagates
|
||||||
test("handles generic prompt error gracefully", async () => {
|
test("propagates generic prompt error", async () => {
|
||||||
|
const throwingMock = async () => {
|
||||||
|
throw new Error("Network connection failed")
|
||||||
|
}
|
||||||
const mockClient = {
|
const mockClient = {
|
||||||
session: {
|
session: {
|
||||||
get: async () => ({ data: { directory: "/project" } }),
|
get: async () => ({ data: { directory: "/project" } }),
|
||||||
create: async () => ({ data: { id: "ses_test_generic_error" } }),
|
create: async () => ({ data: { id: "ses_test_generic_error" } }),
|
||||||
prompt: async () => {
|
prompt: throwingMock,
|
||||||
throw new Error("Network connection failed")
|
promptAsync: throwingMock,
|
||||||
},
|
|
||||||
messages: async () => ({ data: [] }),
|
messages: async () => ({ data: [] }),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -184,13 +182,9 @@ describe("look-at tool", () => {
|
|||||||
ask: async () => {},
|
ask: async () => {},
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await tool.execute(
|
await expect(
|
||||||
{ file_path: "/test/file.pdf", goal: "extract text" },
|
tool.execute({ file_path: "/test/file.pdf", goal: "extract text" }, toolContext)
|
||||||
toolContext
|
).rejects.toThrow("Network connection failed")
|
||||||
)
|
|
||||||
|
|
||||||
expect(result).toContain("Error: Failed to send prompt")
|
|
||||||
expect(result).toContain("Network connection failed")
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -220,6 +214,10 @@ describe("look-at tool", () => {
|
|||||||
promptBody = input.body
|
promptBody = input.body
|
||||||
return { data: {} }
|
return { data: {} }
|
||||||
},
|
},
|
||||||
|
promptAsync: async (input: any) => {
|
||||||
|
promptBody = input.body
|
||||||
|
return { data: {} }
|
||||||
|
},
|
||||||
messages: async () => ({
|
messages: async () => ({
|
||||||
data: [
|
data: [
|
||||||
{ info: { role: "assistant", time: { created: 1 } }, parts: [{ type: "text", text: "done" }] },
|
{ info: { role: "assistant", time: { created: 1 } }, parts: [{ type: "text", text: "done" }] },
|
||||||
@ -274,6 +272,10 @@ describe("look-at tool", () => {
|
|||||||
promptBody = input.body
|
promptBody = input.body
|
||||||
return { data: {} }
|
return { data: {} }
|
||||||
},
|
},
|
||||||
|
promptAsync: async (input: any) => {
|
||||||
|
promptBody = input.body
|
||||||
|
return { data: {} }
|
||||||
|
},
|
||||||
messages: async () => ({
|
messages: async () => ({
|
||||||
data: [
|
data: [
|
||||||
{ info: { role: "assistant", time: { created: 1 } }, parts: [{ type: "text", text: "analyzed" }] },
|
{ info: { role: "assistant", time: { created: 1 } }, parts: [{ type: "text", text: "analyzed" }] },
|
||||||
@ -327,6 +329,10 @@ describe("look-at tool", () => {
|
|||||||
promptBody = input.body
|
promptBody = input.body
|
||||||
return { data: {} }
|
return { data: {} }
|
||||||
},
|
},
|
||||||
|
promptAsync: async (input: any) => {
|
||||||
|
promptBody = input.body
|
||||||
|
return { data: {} }
|
||||||
|
},
|
||||||
messages: async () => ({
|
messages: async () => ({
|
||||||
data: [
|
data: [
|
||||||
{ info: { role: "assistant", time: { created: 1 } }, parts: [{ type: "text", text: "analyzed" }] },
|
{ info: { role: "assistant", time: { created: 1 } }, parts: [{ type: "text", text: "analyzed" }] },
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user