test(tools): remove unsafe test assertions
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -18,7 +18,7 @@ describe("createBackgroundTask metadata", () => {
|
|||||||
// #given
|
// #given
|
||||||
clearPendingStore()
|
clearPendingStore()
|
||||||
|
|
||||||
const manager = {
|
const manager = testCoerce<BackgroundManager>({
|
||||||
launch: mock(() => Promise.resolve({
|
launch: mock(() => Promise.resolve({
|
||||||
id: "task-1",
|
id: "task-1",
|
||||||
sessionID: null,
|
sessionID: null,
|
||||||
@@ -27,12 +27,12 @@ describe("createBackgroundTask metadata", () => {
|
|||||||
status: "pending",
|
status: "pending",
|
||||||
})),
|
})),
|
||||||
getTask: mock(() => undefined),
|
getTask: mock(() => undefined),
|
||||||
} as unknown as BackgroundManager
|
})
|
||||||
const client = {
|
const client = testCoerce<PluginInput["client"]>({
|
||||||
session: {
|
session: {
|
||||||
messages: mock(() => Promise.resolve({ data: [] })),
|
messages: mock(() => Promise.resolve({ data: [] })),
|
||||||
},
|
},
|
||||||
} as unknown as PluginInput["client"]
|
})
|
||||||
|
|
||||||
let capturedMetadata: { title?: string; metadata?: Record<string, unknown> } | undefined
|
let capturedMetadata: { title?: string; metadata?: Record<string, unknown> } | undefined
|
||||||
const tool = createBackgroundTask(manager, client)
|
const tool = createBackgroundTask(manager, client)
|
||||||
|
|||||||
@@ -21,16 +21,16 @@ describe("createBackgroundTask", () => {
|
|||||||
}))
|
}))
|
||||||
const getTaskMock = mock()
|
const getTaskMock = mock()
|
||||||
|
|
||||||
const mockManager = {
|
const mockManager = testCoerce<BackgroundManager>({
|
||||||
launch: launchMock,
|
launch: launchMock,
|
||||||
getTask: getTaskMock,
|
getTask: getTaskMock,
|
||||||
} as unknown as BackgroundManager
|
})
|
||||||
|
|
||||||
const mockClient = {
|
const mockClient = testCoerce<PluginInput["client"]>({
|
||||||
session: {
|
session: {
|
||||||
messages: mock(() => Promise.resolve({ data: [] })),
|
messages: mock(() => Promise.resolve({ data: [] })),
|
||||||
},
|
},
|
||||||
} as unknown as PluginInput["client"]
|
})
|
||||||
|
|
||||||
const tool = createBackgroundTask(mockManager, mockClient)
|
const tool = createBackgroundTask(mockManager, mockClient)
|
||||||
|
|
||||||
|
|||||||
@@ -66,10 +66,10 @@ describe("background_output full_session", () => {
|
|||||||
const manager = createMockManager(task)
|
const manager = createMockManager(task)
|
||||||
const client = createMockClient({})
|
const client = createMockClient({})
|
||||||
const tool = createBackgroundOutput(manager, client)
|
const tool = createBackgroundOutput(manager, client)
|
||||||
const ctxWithCallId = {
|
const ctxWithCallId = testCoerce<ToolContext>({
|
||||||
...mockContext,
|
...mockContext,
|
||||||
callID: "call-1",
|
callID: "call-1",
|
||||||
} as unknown as ToolContext
|
})
|
||||||
|
|
||||||
// #when
|
// #when
|
||||||
await tool.execute({ task_id: "task-1" }, ctxWithCallId)
|
await tool.execute({ task_id: "task-1" }, ctxWithCallId)
|
||||||
@@ -93,10 +93,10 @@ describe("background_output full_session", () => {
|
|||||||
const manager = createMockManager(task)
|
const manager = createMockManager(task)
|
||||||
const client = createMockClient({})
|
const client = createMockClient({})
|
||||||
const tool = createBackgroundOutput(manager, client)
|
const tool = createBackgroundOutput(manager, client)
|
||||||
const ctxWithCallId = {
|
const ctxWithCallId = testCoerce<ToolContext>({
|
||||||
...mockContext,
|
...mockContext,
|
||||||
callID: "call-1",
|
callID: "call-1",
|
||||||
} as unknown as ToolContext
|
})
|
||||||
|
|
||||||
// #when
|
// #when
|
||||||
await tool.execute({ task_id: "task-1" }, ctxWithCallId)
|
await tool.execute({ task_id: "task-1" }, ctxWithCallId)
|
||||||
@@ -387,7 +387,7 @@ describe("background_cancel", () => {
|
|||||||
// #given
|
// #given
|
||||||
const task = createTask({ status: "running" })
|
const task = createTask({ status: "running" })
|
||||||
const cancelled: string[] = []
|
const cancelled: string[] = []
|
||||||
const manager = {
|
const manager = testCoerce<BackgroundManager>({
|
||||||
getTask: (id: string) => (id === task.id ? task : undefined),
|
getTask: (id: string) => (id === task.id ? task : undefined),
|
||||||
getAllDescendantTasks: () => [task],
|
getAllDescendantTasks: () => [task],
|
||||||
cancelTask: async (taskId: string) => {
|
cancelTask: async (taskId: string) => {
|
||||||
@@ -395,7 +395,7 @@ describe("background_cancel", () => {
|
|||||||
task.status = "cancelled"
|
task.status = "cancelled"
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
} as unknown as BackgroundManager
|
})
|
||||||
const client = { session: { abort: async () => ({}) } } as BackgroundCancelClient
|
const client = { session: { abort: async () => ({}) } } as BackgroundCancelClient
|
||||||
const tool = createBackgroundCancel(manager, client)
|
const tool = createBackgroundCancel(manager, client)
|
||||||
|
|
||||||
@@ -412,7 +412,7 @@ describe("background_cancel", () => {
|
|||||||
const taskA = createTask({ id: "task-a", status: "running" })
|
const taskA = createTask({ id: "task-a", status: "running" })
|
||||||
const taskB = createTask({ id: "task-b", status: "pending" })
|
const taskB = createTask({ id: "task-b", status: "pending" })
|
||||||
const cancelled: string[] = []
|
const cancelled: string[] = []
|
||||||
const manager = {
|
const manager = testCoerce<BackgroundManager>({
|
||||||
getTask: () => undefined,
|
getTask: () => undefined,
|
||||||
getAllDescendantTasks: () => [taskA, taskB],
|
getAllDescendantTasks: () => [taskA, taskB],
|
||||||
cancelTask: async (taskId: string) => {
|
cancelTask: async (taskId: string) => {
|
||||||
@@ -421,7 +421,7 @@ describe("background_cancel", () => {
|
|||||||
task.status = "cancelled"
|
task.status = "cancelled"
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
} as unknown as BackgroundManager
|
})
|
||||||
const client = { session: { abort: async () => ({}) } } as BackgroundCancelClient
|
const client = { session: { abort: async () => ({}) } } as BackgroundCancelClient
|
||||||
const tool = createBackgroundCancel(manager, client)
|
const tool = createBackgroundCancel(manager, client)
|
||||||
|
|
||||||
@@ -437,7 +437,7 @@ describe("background_cancel", () => {
|
|||||||
// #given
|
// #given
|
||||||
const taskA = createTask({ id: "task-a", status: "running", sessionId: "ses-a", description: "running task" })
|
const taskA = createTask({ id: "task-a", status: "running", sessionId: "ses-a", description: "running task" })
|
||||||
const taskB = createTask({ id: "task-b", status: "pending", sessionId: undefined, description: "pending task" })
|
const taskB = createTask({ id: "task-b", status: "pending", sessionId: undefined, description: "pending task" })
|
||||||
const manager = {
|
const manager = testCoerce<BackgroundManager>({
|
||||||
getTask: () => undefined,
|
getTask: () => undefined,
|
||||||
getAllDescendantTasks: () => [taskA, taskB],
|
getAllDescendantTasks: () => [taskA, taskB],
|
||||||
cancelTask: async (taskId: string) => {
|
cancelTask: async (taskId: string) => {
|
||||||
@@ -445,7 +445,7 @@ describe("background_cancel", () => {
|
|||||||
task.status = "cancelled"
|
task.status = "cancelled"
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
} as unknown as BackgroundManager
|
})
|
||||||
const client = { session: { abort: async () => ({}) } } as BackgroundCancelClient
|
const client = { session: { abort: async () => ({}) } } as BackgroundCancelClient
|
||||||
const tool = createBackgroundCancel(manager, client)
|
const tool = createBackgroundCancel(manager, client)
|
||||||
|
|
||||||
@@ -461,7 +461,7 @@ describe("background_cancel", () => {
|
|||||||
// #given
|
// #given
|
||||||
const task = createTask({ id: "task-1", status: "running" })
|
const task = createTask({ id: "task-1", status: "running" })
|
||||||
const cancelOptions: Array<{ taskId: string; options: unknown }> = []
|
const cancelOptions: Array<{ taskId: string; options: unknown }> = []
|
||||||
const manager = {
|
const manager = testCoerce<BackgroundManager>({
|
||||||
getTask: (id: string) => (id === task.id ? task : undefined),
|
getTask: (id: string) => (id === task.id ? task : undefined),
|
||||||
getAllDescendantTasks: () => [task],
|
getAllDescendantTasks: () => [task],
|
||||||
cancelTask: async (taskId: string, options?: unknown) => {
|
cancelTask: async (taskId: string, options?: unknown) => {
|
||||||
@@ -469,7 +469,7 @@ describe("background_cancel", () => {
|
|||||||
task.status = "cancelled"
|
task.status = "cancelled"
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
} as unknown as BackgroundManager
|
})
|
||||||
const client = { session: { abort: async () => ({}) } } as BackgroundCancelClient
|
const client = { session: { abort: async () => ({}) } } as BackgroundCancelClient
|
||||||
const tool = createBackgroundCancel(manager, client)
|
const tool = createBackgroundCancel(manager, client)
|
||||||
|
|
||||||
@@ -487,7 +487,7 @@ describe("background_cancel", () => {
|
|||||||
// #given
|
// #given
|
||||||
const task = createTask({ id: "task-1", status: "running" })
|
const task = createTask({ id: "task-1", status: "running" })
|
||||||
const cancelOptions: Array<{ taskId: string; options: unknown }> = []
|
const cancelOptions: Array<{ taskId: string; options: unknown }> = []
|
||||||
const manager = {
|
const manager = testCoerce<BackgroundManager>({
|
||||||
getTask: (id: string) => (id === task.id ? task : undefined),
|
getTask: (id: string) => (id === task.id ? task : undefined),
|
||||||
getAllDescendantTasks: () => [task],
|
getAllDescendantTasks: () => [task],
|
||||||
cancelTask: async (taskId: string, options?: unknown) => {
|
cancelTask: async (taskId: string, options?: unknown) => {
|
||||||
@@ -495,7 +495,7 @@ describe("background_cancel", () => {
|
|||||||
task.status = "cancelled"
|
task.status = "cancelled"
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
} as unknown as BackgroundManager
|
})
|
||||||
const client = { session: { abort: async () => ({}) } } as BackgroundCancelClient
|
const client = { session: { abort: async () => ({}) } } as BackgroundCancelClient
|
||||||
const tool = createBackgroundCancel(manager, client)
|
const tool = createBackgroundCancel(manager, client)
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ const { describe, test, expect, mock, beforeEach } = require("bun:test")
|
|||||||
const { resolveCallableAgents, clearCallableAgentsCache } = require("./agent-resolver")
|
const { resolveCallableAgents, clearCallableAgentsCache } = require("./agent-resolver")
|
||||||
const { ALLOWED_AGENTS } = require("./constants")
|
const { ALLOWED_AGENTS } = require("./constants")
|
||||||
|
|
||||||
function createMockClient(agents = []) {
|
function createMockClient(agents: Array<Record<string, string>> = []) {
|
||||||
return {
|
return {
|
||||||
app: {
|
app: {
|
||||||
agents: mock(() => Promise.resolve({ data: agents })),
|
agents: mock(() => Promise.resolve({ data: agents })),
|
||||||
|
|||||||
@@ -37,12 +37,12 @@ describe("call-omo-agent createOrGetSession", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result = await createOrGetSession(args as any, toolContext as any, ctx as any)
|
const result = await createOrGetSession(testCoerce(args), testCoerce(toolContext), testCoerce(ctx))
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toEqual({ sessionID: "ses_child", isNew: true })
|
expect(result).toEqual({ sessionID: "ses_child", isNew: true })
|
||||||
expect(createCalls).toHaveLength(1)
|
expect(createCalls).toHaveLength(1)
|
||||||
const createBody = (createCalls[0] as any)?.body
|
const createBody = (testCoerce(createCalls[0]))?.body
|
||||||
expect(createBody?.parentID).toBe("ses_parent")
|
expect(createBody?.parentID).toBe("ses_parent")
|
||||||
expect(createBody?.permission).toBeUndefined()
|
expect(createBody?.permission).toBeUndefined()
|
||||||
expect(subagentSessions.has("ses_child")).toBe(true)
|
expect(subagentSessions.has("ses_child")).toBe(true)
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ describe("call-omo-agent resolveOrCreateSessionId", () => {
|
|||||||
const { parentDirectory, contextDirectory } = options
|
const { parentDirectory, contextDirectory } = options
|
||||||
const parentSessionData = parentDirectory ? { data: { directory: parentDirectory } } : { data: {} }
|
const parentSessionData = parentDirectory ? { data: { directory: parentDirectory } } : { data: {} }
|
||||||
|
|
||||||
const ctx = {
|
const ctx = testCoerce<Parameters<typeof resolveOrCreateSessionId>[0]>({
|
||||||
directory: contextDirectory,
|
directory: contextDirectory,
|
||||||
client: {
|
client: {
|
||||||
session: {
|
session: {
|
||||||
@@ -31,7 +31,7 @@ describe("call-omo-agent resolveOrCreateSessionId", () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as unknown as Parameters<typeof resolveOrCreateSessionId>[0]
|
})
|
||||||
|
|
||||||
const args = {
|
const args = {
|
||||||
description: "sync test",
|
description: "sync test",
|
||||||
|
|||||||
@@ -389,7 +389,7 @@ describe("executeSync", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//#when
|
//#when
|
||||||
await executeSync(args, toolContext, ctx as any, deps, undefined, spawnReservation)
|
await executeSync(args, toolContext, testCoerce(ctx), deps, undefined, spawnReservation)
|
||||||
|
|
||||||
//#then
|
//#then
|
||||||
expect(spawnReservation.commit).toHaveBeenCalledTimes(1)
|
expect(spawnReservation.commit).toHaveBeenCalledTimes(1)
|
||||||
|
|||||||
@@ -14,6 +14,10 @@ type SessionWithPromptAsync = {
|
|||||||
promptAsync: (opts: { path: { id: string }; body: Record<string, unknown> }) => Promise<unknown>
|
promptAsync: (opts: { path: { id: string }; body: Record<string, unknown> }) => Promise<unknown>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hasPromptAsync(session: PluginInput["client"]["session"]): session is PluginInput["client"]["session"] & SessionWithPromptAsync {
|
||||||
|
return "promptAsync" in session && typeof session.promptAsync === "function"
|
||||||
|
}
|
||||||
|
|
||||||
type ExecuteSyncDeps = {
|
type ExecuteSyncDeps = {
|
||||||
createOrGetSession: typeof createOrGetSession
|
createOrGetSession: typeof createOrGetSession
|
||||||
waitForCompletion: typeof waitForCompletion
|
waitForCompletion: typeof waitForCompletion
|
||||||
@@ -102,7 +106,11 @@ export async function executeSync(
|
|||||||
const normalizedSubagentType = stripAgentListSortPrefix(args.subagent_type)
|
const normalizedSubagentType = stripAgentListSortPrefix(args.subagent_type)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await (ctx.client.session as unknown as SessionWithPromptAsync).promptAsync({
|
if (!hasPromptAsync(ctx.client.session)) {
|
||||||
|
return `Error: Failed to send prompt: promptAsync is not available on this OpenCode client.\n\n<task_metadata>\nsession_id: ${sessionID}\n</task_metadata>`
|
||||||
|
}
|
||||||
|
|
||||||
|
await ctx.client.session.promptAsync({
|
||||||
path: { id: sessionID },
|
path: { id: sessionID },
|
||||||
body: {
|
body: {
|
||||||
agent: normalizedSubagentType,
|
agent: normalizedSubagentType,
|
||||||
|
|||||||
@@ -1,7 +1,25 @@
|
|||||||
import type { OpencodeClient } from "./types"
|
import type { OpencodeClient } from "./types"
|
||||||
import { log } from "../../shared/logger"
|
import { log } from "../../shared/logger"
|
||||||
|
import { isRecord } from "../../shared/record-type-guard"
|
||||||
import { readConnectedProvidersCache, readProviderModelsCache } from "../../shared/connected-providers-cache"
|
import { readConnectedProvidersCache, readProviderModelsCache } from "../../shared/connected-providers-cache"
|
||||||
|
|
||||||
|
type ModelListClient = OpencodeClient & {
|
||||||
|
model: { list: () => Promise<unknown> }
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasModelList(client: OpencodeClient): client is ModelListClient {
|
||||||
|
return "model" in client && isRecord(client.model) && typeof client.model.list === "function"
|
||||||
|
}
|
||||||
|
|
||||||
|
function isModelRow(value: unknown): value is { provider: string; id: string } {
|
||||||
|
return isRecord(value) && typeof value.provider === "string" && typeof value.id === "string"
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractModelRows(result: unknown): Array<{ provider: string; id: string }> {
|
||||||
|
const rows = Array.isArray(result) ? result : isRecord(result) && Array.isArray(result.data) ? result.data : []
|
||||||
|
return rows.filter(isModelRow)
|
||||||
|
}
|
||||||
|
|
||||||
function addFromProviderModels(
|
function addFromProviderModels(
|
||||||
out: Set<string>,
|
out: Set<string>,
|
||||||
providerID: string,
|
providerID: string,
|
||||||
@@ -35,24 +53,17 @@ export async function getAvailableModelsForDelegateTask(client: OpencodeClient):
|
|||||||
return new Set()
|
return new Set()
|
||||||
}
|
}
|
||||||
|
|
||||||
const modelList = (client as unknown as { model?: { list?: () => Promise<unknown> } })
|
if (!hasModelList(client)) {
|
||||||
?.model
|
|
||||||
?.list
|
|
||||||
|
|
||||||
if (!modelList) {
|
|
||||||
return new Set()
|
return new Set()
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await modelList()
|
const result = await client.model.list()
|
||||||
const rows = Array.isArray(result)
|
const rows = extractModelRows(result)
|
||||||
? result
|
|
||||||
: ((result as { data?: unknown }).data as Array<{ provider?: string; id?: string }> | undefined) ?? []
|
|
||||||
|
|
||||||
const connected = new Set(connectedProviders)
|
const connected = new Set(connectedProviders)
|
||||||
const out = new Set<string>()
|
const out = new Set<string>()
|
||||||
for (const row of rows) {
|
for (const row of rows) {
|
||||||
if (!row?.provider || !row?.id) continue
|
|
||||||
if (!connected.has(row.provider)) continue
|
if (!connected.has(row.provider)) continue
|
||||||
out.add(`${row.provider}/${row.id}`)
|
out.add(`${row.provider}/${row.id}`)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ describe("resolveCategoryExecution", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const createMockExecutorContext = (): ExecutorContext => ({
|
const createMockExecutorContext = (): ExecutorContext => ({
|
||||||
client: {} as any,
|
client: testCoerce({}),
|
||||||
manager: {} as any,
|
manager: testCoerce({}),
|
||||||
directory: "/tmp/test",
|
directory: "/tmp/test",
|
||||||
userCategories: {},
|
userCategories: {},
|
||||||
sisyphusJuniorModel: undefined,
|
sisyphusJuniorModel: undefined,
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ describe("task tool metadata awaiting", () => {
|
|||||||
subagent_type: "explore",
|
subagent_type: "explore",
|
||||||
}
|
}
|
||||||
|
|
||||||
const executorCtx = {
|
const executorCtx = testCoerce({
|
||||||
manager: {
|
manager: {
|
||||||
launch: async () => ({
|
launch: async () => ({
|
||||||
id: "task_1",
|
id: "task_1",
|
||||||
@@ -40,7 +40,7 @@ describe("task tool metadata awaiting", () => {
|
|||||||
}),
|
}),
|
||||||
getTask: () => undefined,
|
getTask: () => undefined,
|
||||||
},
|
},
|
||||||
} as any
|
})
|
||||||
|
|
||||||
const parentContext = {
|
const parentContext = {
|
||||||
sessionID: "ses_parent",
|
sessionID: "ses_parent",
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ describe("metadata model unification", () => {
|
|||||||
load_skills: [], run_in_background: true, subagent_type: "explore",
|
load_skills: [], run_in_background: true, subagent_type: "explore",
|
||||||
}
|
}
|
||||||
|
|
||||||
await executeBackgroundTask(args, ctx, {
|
await executeBackgroundTask(args, ctx, testCoerce({
|
||||||
manager: {
|
manager: {
|
||||||
launch: async () => ({
|
launch: async () => ({
|
||||||
id: "bg_1", description: "test", agent: "explore",
|
id: "bg_1", description: "test", agent: "explore",
|
||||||
@@ -71,7 +71,7 @@ describe("metadata model unification", () => {
|
|||||||
}),
|
}),
|
||||||
getTask: () => undefined,
|
getTask: () => undefined,
|
||||||
},
|
},
|
||||||
} as any, parentContext, "explore", MODEL, undefined)
|
}), parentContext, "explore", MODEL, undefined)
|
||||||
|
|
||||||
const meta = ctx.captured.find((m: any) => m.metadata?.sessionId)
|
const meta = ctx.captured.find((m: any) => m.metadata?.sessionId)
|
||||||
expect(meta).toBeDefined()
|
expect(meta).toBeDefined()
|
||||||
@@ -92,7 +92,7 @@ describe("metadata model unification", () => {
|
|||||||
}
|
}
|
||||||
await executeUnstableAgentTask(
|
await executeUnstableAgentTask(
|
||||||
args, ctx,
|
args, ctx,
|
||||||
{
|
testCoerce({
|
||||||
manager: {
|
manager: {
|
||||||
launch: async () => launchedTask,
|
launch: async () => launchedTask,
|
||||||
getTask: () => launchedTask,
|
getTask: () => launchedTask,
|
||||||
@@ -109,7 +109,7 @@ describe("metadata model unification", () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
syncPollTimeoutMs: 100,
|
syncPollTimeoutMs: 100,
|
||||||
} as any,
|
}),
|
||||||
parentContext, "explore", MODEL, undefined, "anthropic/claude-sonnet-4-6",
|
parentContext, "explore", MODEL, undefined, "anthropic/claude-sonnet-4-6",
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -126,14 +126,14 @@ describe("metadata model unification", () => {
|
|||||||
load_skills: [], run_in_background: true, task_id: "ses_resumed",
|
load_skills: [], run_in_background: true, task_id: "ses_resumed",
|
||||||
}
|
}
|
||||||
|
|
||||||
await executeBackgroundContinuation(args, ctx, {
|
await executeBackgroundContinuation(args, ctx, testCoerce({
|
||||||
manager: {
|
manager: {
|
||||||
resume: async () => ({
|
resume: async () => ({
|
||||||
id: "bg_2", description: "continue", agent: "explore",
|
id: "bg_2", description: "continue", agent: "explore",
|
||||||
status: "running", sessionId: "ses_resumed", model: MODEL,
|
status: "running", sessionId: "ses_resumed", model: MODEL,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
} as any, parentContext)
|
}), parentContext)
|
||||||
|
|
||||||
const meta = ctx.captured.find((m: any) => m.metadata?.sessionId)
|
const meta = ctx.captured.find((m: any) => m.metadata?.sessionId)
|
||||||
expect(meta).toBeDefined()
|
expect(meta).toBeDefined()
|
||||||
@@ -153,7 +153,7 @@ describe("metadata model unification", () => {
|
|||||||
fetchSyncResult: async () => ({ ok: true as const, textContent: "done" }),
|
fetchSyncResult: async () => ({ ok: true as const, textContent: "done" }),
|
||||||
}
|
}
|
||||||
|
|
||||||
await executeSyncContinuation(args, ctx, {
|
await executeSyncContinuation(args, ctx, testCoerce({
|
||||||
client: {
|
client: {
|
||||||
session: {
|
session: {
|
||||||
messages: async () => ({
|
messages: async () => ({
|
||||||
@@ -162,7 +162,7 @@ describe("metadata model unification", () => {
|
|||||||
prompt: async () => ({}),
|
prompt: async () => ({}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as any, parentContext, deps)
|
}), parentContext, deps)
|
||||||
|
|
||||||
const meta = ctx.captured.find((m: any) => m.metadata?.sessionId)
|
const meta = ctx.captured.find((m: any) => m.metadata?.sessionId)
|
||||||
expect(meta).toBeDefined()
|
expect(meta).toBeDefined()
|
||||||
@@ -206,7 +206,7 @@ describe("metadata model unification", () => {
|
|||||||
load_skills: [], run_in_background: true, subagent_type: "explore",
|
load_skills: [], run_in_background: true, subagent_type: "explore",
|
||||||
}
|
}
|
||||||
|
|
||||||
await executeBackgroundTask(args, ctx, {
|
await executeBackgroundTask(args, ctx, testCoerce({
|
||||||
manager: {
|
manager: {
|
||||||
launch: async () => ({
|
launch: async () => ({
|
||||||
id: "bg_1", description: "test", agent: "explore",
|
id: "bg_1", description: "test", agent: "explore",
|
||||||
@@ -214,7 +214,7 @@ describe("metadata model unification", () => {
|
|||||||
}),
|
}),
|
||||||
getTask: () => undefined,
|
getTask: () => undefined,
|
||||||
},
|
},
|
||||||
} as any, parentContext, "explore", undefined, undefined)
|
}), parentContext, "explore", undefined, undefined)
|
||||||
|
|
||||||
const meta = ctx.captured.find((m: any) => m.metadata?.sessionId)
|
const meta = ctx.captured.find((m: any) => m.metadata?.sessionId)
|
||||||
expect(meta).toBeDefined()
|
expect(meta).toBeDefined()
|
||||||
@@ -236,7 +236,7 @@ describe("metadata model unification", () => {
|
|||||||
|
|
||||||
await executeUnstableAgentTask(
|
await executeUnstableAgentTask(
|
||||||
args, ctx,
|
args, ctx,
|
||||||
{
|
testCoerce({
|
||||||
manager: {
|
manager: {
|
||||||
launch: async () => launchedTask,
|
launch: async () => launchedTask,
|
||||||
getTask: () => launchedTask,
|
getTask: () => launchedTask,
|
||||||
@@ -253,7 +253,7 @@ describe("metadata model unification", () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
syncPollTimeoutMs: 100,
|
syncPollTimeoutMs: 100,
|
||||||
} as any,
|
}),
|
||||||
parentContext, "explore", undefined, undefined, "anthropic/claude-sonnet-4-6",
|
parentContext, "explore", undefined, undefined, "anthropic/claude-sonnet-4-6",
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -270,14 +270,14 @@ describe("metadata model unification", () => {
|
|||||||
load_skills: [], run_in_background: true, task_id: "ses_resumed",
|
load_skills: [], run_in_background: true, task_id: "ses_resumed",
|
||||||
}
|
}
|
||||||
|
|
||||||
await executeBackgroundContinuation(args, ctx, {
|
await executeBackgroundContinuation(args, ctx, testCoerce({
|
||||||
manager: {
|
manager: {
|
||||||
resume: async () => ({
|
resume: async () => ({
|
||||||
id: "bg_2", description: "continue", agent: "explore",
|
id: "bg_2", description: "continue", agent: "explore",
|
||||||
status: "running", sessionId: "ses_resumed",
|
status: "running", sessionId: "ses_resumed",
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
} as any, parentContext)
|
}), parentContext)
|
||||||
|
|
||||||
const meta = ctx.captured.find((m: any) => m.metadata?.sessionId)
|
const meta = ctx.captured.find((m: any) => m.metadata?.sessionId)
|
||||||
expect(meta).toBeDefined()
|
expect(meta).toBeDefined()
|
||||||
@@ -297,14 +297,14 @@ describe("metadata model unification", () => {
|
|||||||
fetchSyncResult: async () => ({ ok: true as const, textContent: "done" }),
|
fetchSyncResult: async () => ({ ok: true as const, textContent: "done" }),
|
||||||
}
|
}
|
||||||
|
|
||||||
await executeSyncContinuation(args, ctx, {
|
await executeSyncContinuation(args, ctx, testCoerce({
|
||||||
client: {
|
client: {
|
||||||
session: {
|
session: {
|
||||||
messages: async () => ({ data: [] }),
|
messages: async () => ({ data: [] }),
|
||||||
prompt: async () => ({}),
|
prompt: async () => ({}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as any, parentContext, deps)
|
}), parentContext, deps)
|
||||||
|
|
||||||
const meta = ctx.captured.find((m: any) => m.metadata?.sessionId)
|
const meta = ctx.captured.find((m: any) => m.metadata?.sessionId)
|
||||||
expect(meta).toBeDefined()
|
expect(meta).toBeDefined()
|
||||||
@@ -381,7 +381,7 @@ describe("metadata model unification", () => {
|
|||||||
category: "visual-engineering", load_skills: [], run_in_background: true, subagent_type: "explore",
|
category: "visual-engineering", load_skills: [], run_in_background: true, subagent_type: "explore",
|
||||||
}
|
}
|
||||||
|
|
||||||
await executeBackgroundTask(args, ctx, {
|
await executeBackgroundTask(args, ctx, testCoerce({
|
||||||
manager: {
|
manager: {
|
||||||
launch: async () => ({
|
launch: async () => ({
|
||||||
id: "bg_variant", description: "test", agent: "explore",
|
id: "bg_variant", description: "test", agent: "explore",
|
||||||
@@ -389,7 +389,7 @@ describe("metadata model unification", () => {
|
|||||||
}),
|
}),
|
||||||
getTask: () => undefined,
|
getTask: () => undefined,
|
||||||
},
|
},
|
||||||
} as any, parentContext, "explore", MODEL_WITH_VARIANT, undefined)
|
}), parentContext, "explore", MODEL_WITH_VARIANT, undefined)
|
||||||
|
|
||||||
const meta = ctx.captured.find((metadataEvent: any) => metadataEvent.metadata?.sessionId)
|
const meta = ctx.captured.find((metadataEvent: any) => metadataEvent.metadata?.sessionId)
|
||||||
expect(meta).toBeDefined()
|
expect(meta).toBeDefined()
|
||||||
@@ -411,7 +411,7 @@ describe("metadata model unification", () => {
|
|||||||
|
|
||||||
await executeUnstableAgentTask(
|
await executeUnstableAgentTask(
|
||||||
args, ctx,
|
args, ctx,
|
||||||
{
|
testCoerce({
|
||||||
manager: {
|
manager: {
|
||||||
launch: async () => launchedTask,
|
launch: async () => launchedTask,
|
||||||
getTask: () => launchedTask,
|
getTask: () => launchedTask,
|
||||||
@@ -428,7 +428,7 @@ describe("metadata model unification", () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
syncPollTimeoutMs: 100,
|
syncPollTimeoutMs: 100,
|
||||||
} as any,
|
}),
|
||||||
parentContext, "explore", MODEL_WITH_VARIANT, undefined, "google/gemini-3.1-pro high",
|
parentContext, "explore", MODEL_WITH_VARIANT, undefined, "google/gemini-3.1-pro high",
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -445,14 +445,14 @@ describe("metadata model unification", () => {
|
|||||||
load_skills: [], run_in_background: true, task_id: "ses_resumed_variant",
|
load_skills: [], run_in_background: true, task_id: "ses_resumed_variant",
|
||||||
}
|
}
|
||||||
|
|
||||||
await executeBackgroundContinuation(args, ctx, {
|
await executeBackgroundContinuation(args, ctx, testCoerce({
|
||||||
manager: {
|
manager: {
|
||||||
resume: async () => ({
|
resume: async () => ({
|
||||||
id: "bg_resume_variant", description: "continue", agent: "explore",
|
id: "bg_resume_variant", description: "continue", agent: "explore",
|
||||||
status: "running", sessionId: "ses_resumed_variant", model: MODEL_WITH_VARIANT,
|
status: "running", sessionId: "ses_resumed_variant", model: MODEL_WITH_VARIANT,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
} as any, parentContext)
|
}), parentContext)
|
||||||
|
|
||||||
const meta = ctx.captured.find((metadataEvent: any) => metadataEvent.metadata?.sessionId)
|
const meta = ctx.captured.find((metadataEvent: any) => metadataEvent.metadata?.sessionId)
|
||||||
expect(meta).toBeDefined()
|
expect(meta).toBeDefined()
|
||||||
@@ -472,7 +472,7 @@ describe("metadata model unification", () => {
|
|||||||
fetchSyncResult: async () => ({ ok: true as const, textContent: "done" }),
|
fetchSyncResult: async () => ({ ok: true as const, textContent: "done" }),
|
||||||
}
|
}
|
||||||
|
|
||||||
await executeSyncContinuation(args, ctx, {
|
await executeSyncContinuation(args, ctx, testCoerce({
|
||||||
client: {
|
client: {
|
||||||
session: {
|
session: {
|
||||||
messages: async () => ({
|
messages: async () => ({
|
||||||
@@ -481,7 +481,7 @@ describe("metadata model unification", () => {
|
|||||||
prompt: async () => ({}),
|
prompt: async () => ({}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as any, parentContext, deps)
|
}), parentContext, deps)
|
||||||
|
|
||||||
const meta = ctx.captured.find((metadataEvent: any) => metadataEvent.metadata?.sessionId)
|
const meta = ctx.captured.find((metadataEvent: any) => metadataEvent.metadata?.sessionId)
|
||||||
expect(meta).toBeDefined()
|
expect(meta).toBeDefined()
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => {
|
|||||||
load_skills: [], run_in_background: true, subagent_type: "explore",
|
load_skills: [], run_in_background: true, subagent_type: "explore",
|
||||||
}
|
}
|
||||||
|
|
||||||
await executeBackgroundTask(args, ctx, {
|
await executeBackgroundTask(args, ctx, testCoerce({
|
||||||
manager: {
|
manager: {
|
||||||
launch: async () => ({
|
launch: async () => ({
|
||||||
id: "bg_abc123", description: "test", agent: "explore",
|
id: "bg_abc123", description: "test", agent: "explore",
|
||||||
@@ -72,7 +72,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => {
|
|||||||
}),
|
}),
|
||||||
getTask: () => undefined,
|
getTask: () => undefined,
|
||||||
},
|
},
|
||||||
} as any, parentContext, "explore", MODEL, undefined)
|
}), parentContext, "explore", MODEL, undefined)
|
||||||
|
|
||||||
const meta = ctx.captured.find((m: any) => m.metadata?.sessionId)
|
const meta = ctx.captured.find((m: any) => m.metadata?.sessionId)
|
||||||
expect(meta).toBeDefined()
|
expect(meta).toBeDefined()
|
||||||
@@ -98,7 +98,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => {
|
|||||||
|
|
||||||
await executeUnstableAgentTask(
|
await executeUnstableAgentTask(
|
||||||
args, ctx,
|
args, ctx,
|
||||||
{
|
testCoerce({
|
||||||
manager: {
|
manager: {
|
||||||
launch: async () => launchedTask,
|
launch: async () => launchedTask,
|
||||||
getTask: () => launchedTask,
|
getTask: () => launchedTask,
|
||||||
@@ -115,7 +115,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
syncPollTimeoutMs: 100,
|
syncPollTimeoutMs: 100,
|
||||||
} as any,
|
}),
|
||||||
parentContext, "explore", MODEL, undefined, "anthropic/claude-sonnet-4-6",
|
parentContext, "explore", MODEL, undefined, "anthropic/claude-sonnet-4-6",
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -136,14 +136,14 @@ describe("taskId and backgroundTaskId metadata consistency", () => {
|
|||||||
load_skills: [], run_in_background: true, task_id: "ses_resumed_x",
|
load_skills: [], run_in_background: true, task_id: "ses_resumed_x",
|
||||||
}
|
}
|
||||||
|
|
||||||
await executeBackgroundContinuation(args, ctx, {
|
await executeBackgroundContinuation(args, ctx, testCoerce({
|
||||||
manager: {
|
manager: {
|
||||||
resume: async () => ({
|
resume: async () => ({
|
||||||
id: "bg_resumed_y", description: "continue", agent: "explore",
|
id: "bg_resumed_y", description: "continue", agent: "explore",
|
||||||
status: "running", sessionId: "ses_resumed_x", model: MODEL,
|
status: "running", sessionId: "ses_resumed_x", model: MODEL,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
} as any, parentContext)
|
}), parentContext)
|
||||||
|
|
||||||
const meta = ctx.captured.find((m: any) => m.metadata?.sessionId)
|
const meta = ctx.captured.find((m: any) => m.metadata?.sessionId)
|
||||||
expect(meta).toBeDefined()
|
expect(meta).toBeDefined()
|
||||||
@@ -160,14 +160,14 @@ describe("taskId and backgroundTaskId metadata consistency", () => {
|
|||||||
load_skills: [], run_in_background: true, task_id: "ses_resumed_x",
|
load_skills: [], run_in_background: true, task_id: "ses_resumed_x",
|
||||||
}
|
}
|
||||||
|
|
||||||
await executeBackgroundContinuation(args, ctx, {
|
await executeBackgroundContinuation(args, ctx, testCoerce({
|
||||||
manager: {
|
manager: {
|
||||||
resume: async () => ({
|
resume: async () => ({
|
||||||
id: "bg_resumed_y", description: "continue", agent: "explore",
|
id: "bg_resumed_y", description: "continue", agent: "explore",
|
||||||
status: "running", sessionId: "ses_resumed_x", model: MODEL, category: "deep",
|
status: "running", sessionId: "ses_resumed_x", model: MODEL, category: "deep",
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
} as any, parentContext)
|
}), parentContext)
|
||||||
|
|
||||||
const meta = ctx.captured.find((item: any) => item.metadata?.sessionId)
|
const meta = ctx.captured.find((item: any) => item.metadata?.sessionId)
|
||||||
expect(meta).toBeDefined()
|
expect(meta).toBeDefined()
|
||||||
@@ -187,14 +187,14 @@ describe("taskId and backgroundTaskId metadata consistency", () => {
|
|||||||
task_id: "ses_resumed_x",
|
task_id: "ses_resumed_x",
|
||||||
}
|
}
|
||||||
|
|
||||||
await executeBackgroundContinuation(args, ctx, {
|
await executeBackgroundContinuation(args, ctx, testCoerce({
|
||||||
manager: {
|
manager: {
|
||||||
resume: async () => ({
|
resume: async () => ({
|
||||||
id: "bg_resumed_y", description: "continue", agent: "explore",
|
id: "bg_resumed_y", description: "continue", agent: "explore",
|
||||||
status: "running", sessionId: "ses_resumed_x", model: MODEL,
|
status: "running", sessionId: "ses_resumed_x", model: MODEL,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
} as any, parentContext)
|
}), parentContext)
|
||||||
|
|
||||||
const meta = ctx.captured.find((item: any) => item.metadata?.sessionId)
|
const meta = ctx.captured.find((item: any) => item.metadata?.sessionId)
|
||||||
expect(meta).toBeDefined()
|
expect(meta).toBeDefined()
|
||||||
@@ -216,7 +216,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => {
|
|||||||
fetchSyncResult: async () => ({ ok: true as const, textContent: "done" }),
|
fetchSyncResult: async () => ({ ok: true as const, textContent: "done" }),
|
||||||
}
|
}
|
||||||
|
|
||||||
await executeSyncContinuation(args, ctx, {
|
await executeSyncContinuation(args, ctx, testCoerce({
|
||||||
client: {
|
client: {
|
||||||
session: {
|
session: {
|
||||||
messages: async () => ({
|
messages: async () => ({
|
||||||
@@ -225,7 +225,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => {
|
|||||||
prompt: async () => ({}),
|
prompt: async () => ({}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as any, parentContext, deps)
|
}), parentContext, deps)
|
||||||
|
|
||||||
const meta = ctx.captured.find((m: any) => m.metadata?.sessionId)
|
const meta = ctx.captured.find((m: any) => m.metadata?.sessionId)
|
||||||
expect(meta).toBeDefined()
|
expect(meta).toBeDefined()
|
||||||
@@ -246,7 +246,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => {
|
|||||||
fetchSyncResult: async () => ({ ok: true as const, textContent: "done" }),
|
fetchSyncResult: async () => ({ ok: true as const, textContent: "done" }),
|
||||||
}
|
}
|
||||||
|
|
||||||
await executeSyncContinuation(args, ctx, {
|
await executeSyncContinuation(args, ctx, testCoerce({
|
||||||
client: {
|
client: {
|
||||||
session: {
|
session: {
|
||||||
messages: async () => ({
|
messages: async () => ({
|
||||||
@@ -255,7 +255,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => {
|
|||||||
prompt: async () => ({}),
|
prompt: async () => ({}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as any, parentContext, deps)
|
}), parentContext, deps)
|
||||||
|
|
||||||
const meta = ctx.captured.find((item: any) => item.metadata?.sessionId)
|
const meta = ctx.captured.find((item: any) => item.metadata?.sessionId)
|
||||||
expect(meta).toBeDefined()
|
expect(meta).toBeDefined()
|
||||||
@@ -275,7 +275,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => {
|
|||||||
fetchSyncResult: async () => ({ ok: true as const, textContent: "done" }),
|
fetchSyncResult: async () => ({ ok: true as const, textContent: "done" }),
|
||||||
}
|
}
|
||||||
|
|
||||||
await executeSyncContinuation(args, ctx, {
|
await executeSyncContinuation(args, ctx, testCoerce({
|
||||||
client: {
|
client: {
|
||||||
session: {
|
session: {
|
||||||
messages: async () => ({
|
messages: async () => ({
|
||||||
@@ -284,7 +284,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => {
|
|||||||
prompt: async () => ({}),
|
prompt: async () => ({}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as any, parentContext, deps)
|
}), parentContext, deps)
|
||||||
|
|
||||||
const meta = ctx.captured.find((item: any) => item.metadata?.sessionId)
|
const meta = ctx.captured.find((item: any) => item.metadata?.sessionId)
|
||||||
expect(meta).toBeDefined()
|
expect(meta).toBeDefined()
|
||||||
@@ -309,7 +309,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => {
|
|||||||
fetchSyncResult: async () => ({ ok: true as const, textContent: "done" }),
|
fetchSyncResult: async () => ({ ok: true as const, textContent: "done" }),
|
||||||
}
|
}
|
||||||
|
|
||||||
await executeSyncContinuation(args, ctx, {
|
await executeSyncContinuation(args, ctx, testCoerce({
|
||||||
client: {
|
client: {
|
||||||
session: {
|
session: {
|
||||||
messages: async () => ({
|
messages: async () => ({
|
||||||
@@ -318,7 +318,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => {
|
|||||||
prompt: async () => ({}),
|
prompt: async () => ({}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as any, parentContext, deps)
|
}), parentContext, deps)
|
||||||
|
|
||||||
const meta = ctx.captured.find((item: any) => item.metadata?.sessionId)
|
const meta = ctx.captured.find((item: any) => item.metadata?.sessionId)
|
||||||
expect(meta).toBeDefined()
|
expect(meta).toBeDefined()
|
||||||
@@ -368,7 +368,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => {
|
|||||||
run_in_background: true,
|
run_in_background: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
await executeBackgroundTask(args, ctx, {
|
await executeBackgroundTask(args, ctx, testCoerce({
|
||||||
manager: {
|
manager: {
|
||||||
launch: async () => ({
|
launch: async () => ({
|
||||||
id: "bg_abc123", description: "test", agent: "Sisyphus-Junior",
|
id: "bg_abc123", description: "test", agent: "Sisyphus-Junior",
|
||||||
@@ -376,7 +376,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => {
|
|||||||
}),
|
}),
|
||||||
getTask: () => undefined,
|
getTask: () => undefined,
|
||||||
},
|
},
|
||||||
} as any, parentContext, "Sisyphus-Junior", MODEL, undefined)
|
}), parentContext, "Sisyphus-Junior", MODEL, undefined)
|
||||||
|
|
||||||
const meta = ctx.captured.find((item: any) => item.metadata?.sessionId)
|
const meta = ctx.captured.find((item: any) => item.metadata?.sessionId)
|
||||||
expect(meta).toBeDefined()
|
expect(meta).toBeDefined()
|
||||||
@@ -402,7 +402,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => {
|
|||||||
|
|
||||||
await executeUnstableAgentTask(
|
await executeUnstableAgentTask(
|
||||||
args, ctx,
|
args, ctx,
|
||||||
{
|
testCoerce({
|
||||||
manager: {
|
manager: {
|
||||||
launch: async () => launchedTask,
|
launch: async () => launchedTask,
|
||||||
getTask: () => launchedTask,
|
getTask: () => launchedTask,
|
||||||
@@ -419,7 +419,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
syncPollTimeoutMs: 100,
|
syncPollTimeoutMs: 100,
|
||||||
} as any,
|
}),
|
||||||
parentContext, "Sisyphus-Junior", MODEL, undefined, "anthropic/claude-sonnet-4-6",
|
parentContext, "Sisyphus-Junior", MODEL, undefined, "anthropic/claude-sonnet-4-6",
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -438,14 +438,14 @@ describe("taskId and backgroundTaskId metadata consistency", () => {
|
|||||||
load_skills: [], run_in_background: true, task_id: "ses_resume_title",
|
load_skills: [], run_in_background: true, task_id: "ses_resume_title",
|
||||||
}
|
}
|
||||||
|
|
||||||
await executeBackgroundContinuation(args, ctx, {
|
await executeBackgroundContinuation(args, ctx, testCoerce({
|
||||||
manager: {
|
manager: {
|
||||||
resume: async () => ({
|
resume: async () => ({
|
||||||
id: "bg_resume_title", description: "continue work", agent: "explore",
|
id: "bg_resume_title", description: "continue work", agent: "explore",
|
||||||
status: "running", sessionId: "ses_resume_title", model: MODEL,
|
status: "running", sessionId: "ses_resume_title", model: MODEL,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
} as any, parentContext)
|
}), parentContext)
|
||||||
|
|
||||||
const meta = ctx.captured.find((item: any) => item.metadata?.sessionId)
|
const meta = ctx.captured.find((item: any) => item.metadata?.sessionId)
|
||||||
expect(meta).toBeDefined()
|
expect(meta).toBeDefined()
|
||||||
@@ -460,7 +460,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => {
|
|||||||
load_skills: [], run_in_background: false, task_id: "ses_sync_title",
|
load_skills: [], run_in_background: false, task_id: "ses_sync_title",
|
||||||
}
|
}
|
||||||
|
|
||||||
await executeSyncContinuation(args, ctx, {
|
await executeSyncContinuation(args, ctx, testCoerce({
|
||||||
client: {
|
client: {
|
||||||
session: {
|
session: {
|
||||||
messages: async () => ({
|
messages: async () => ({
|
||||||
@@ -469,7 +469,7 @@ describe("taskId and backgroundTaskId metadata consistency", () => {
|
|||||||
prompt: async () => ({}),
|
prompt: async () => ({}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as any, parentContext, {
|
}), parentContext, {
|
||||||
pollSyncSession: async () => null,
|
pollSyncSession: async () => null,
|
||||||
fetchSyncResult: async () => ({ ok: true as const, textContent: "done" }),
|
fetchSyncResult: async () => ({ ok: true as const, textContent: "done" }),
|
||||||
})
|
})
|
||||||
@@ -500,8 +500,8 @@ describe("taskId and backgroundTaskId metadata consistency", () => {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const bgOutput = createBackgroundOutput(manager as any, client as any)
|
const bgOutput = createBackgroundOutput(testCoerce(manager), testCoerce(client))
|
||||||
await bgOutput.execute({ task_id: "bg_output_xyz" } as any, ctx as any)
|
await bgOutput.execute(testCoerce({ task_id: "bg_output_xyz" }), testCoerce(ctx))
|
||||||
|
|
||||||
const meta = ctx.captured.find((m: any) => m.metadata?.backgroundTaskId)
|
const meta = ctx.captured.find((m: any) => m.metadata?.backgroundTaskId)
|
||||||
expect(meta).toBeDefined()
|
expect(meta).toBeDefined()
|
||||||
|
|||||||
@@ -18,14 +18,14 @@ function createDelegateTask(...args: Parameters<typeof import("./tools").createD
|
|||||||
const toolDefinition = createDelegateTask({ manager: {} as never, client: {} as never, directory: "/tmp/test" })
|
const toolDefinition = createDelegateTask({ manager: {} as never, client: {} as never, directory: "/tmp/test" })
|
||||||
|
|
||||||
//#when
|
//#when
|
||||||
const categorySchema = toolDefinition.args.category as unknown as {
|
const categorySchema = testCoerce<{
|
||||||
def: {
|
def: {
|
||||||
type: string
|
type: string
|
||||||
innerType: {
|
innerType: {
|
||||||
def: { type: string }
|
def: { type: string }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}>(toolDefinition.args.category)
|
||||||
|
|
||||||
//#then
|
//#then
|
||||||
expect(categorySchema.def.type).toBe("optional")
|
expect(categorySchema.def.type).toBe("optional")
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ describe("executeUnstableAgentTask session permission", () => {
|
|||||||
metadata: () => {},
|
metadata: () => {},
|
||||||
abort: new AbortController().signal,
|
abort: new AbortController().signal,
|
||||||
} satisfies Parameters<typeof executeUnstableAgentTask>[1]
|
} satisfies Parameters<typeof executeUnstableAgentTask>[1]
|
||||||
const executorContext = {
|
const executorContext = testCoerce<Parameters<typeof executeUnstableAgentTask>[2]>({
|
||||||
manager: mockManager,
|
manager: mockManager,
|
||||||
client: {
|
client: {
|
||||||
session: {
|
session: {
|
||||||
@@ -41,7 +41,7 @@ describe("executeUnstableAgentTask session permission", () => {
|
|||||||
messages: async () => ({ data: [] }),
|
messages: async () => ({ data: [] }),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
} as unknown as Parameters<typeof executeUnstableAgentTask>[2]
|
})
|
||||||
const parentContext = {
|
const parentContext = {
|
||||||
sessionID: "parent-session",
|
sessionID: "parent-session",
|
||||||
messageID: "msg_parent",
|
messageID: "msg_parent",
|
||||||
|
|||||||
@@ -51,9 +51,9 @@ describe("normalizeHashlineEdits", () => {
|
|||||||
|
|
||||||
it("rejects legacy payload without op", () => {
|
it("rejects legacy payload without op", () => {
|
||||||
//#given
|
//#given
|
||||||
const input = [{ type: "set_line", line: "2#VK", text: "updated" }] as unknown as Parameters<
|
const input = testCoerce<Parameters<
|
||||||
typeof normalizeHashlineEdits
|
typeof normalizeHashlineEdits
|
||||||
>[0]
|
>[0]>([{ type: "set_line", line: "2#VK", text: "updated" }])
|
||||||
|
|
||||||
//#when / #then
|
//#when / #then
|
||||||
expect(() => normalizeHashlineEdits(input)).toThrow(/legacy format was removed/i)
|
expect(() => normalizeHashlineEdits(input)).toThrow(/legacy format was removed/i)
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ import * as os from "node:os"
|
|||||||
import * as path from "node:path"
|
import * as path from "node:path"
|
||||||
|
|
||||||
function createMockContext(): ToolContext {
|
function createMockContext(): ToolContext {
|
||||||
return {
|
return testCoerce<ToolContext>({
|
||||||
sessionID: "test",
|
sessionID: "test",
|
||||||
messageID: "test",
|
messageID: "test",
|
||||||
agent: "test",
|
agent: "test",
|
||||||
abort: new AbortController().signal,
|
abort: new AbortController().signal,
|
||||||
metadata: mock(() => {}),
|
metadata: mock(() => {}),
|
||||||
ask: async () => {},
|
ask: async () => {},
|
||||||
} as unknown as ToolContext
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("createHashlineEditTool", () => {
|
describe("createHashlineEditTool", () => {
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ describe("resolveMultimodalLookerAgentMetadata", () => {
|
|||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
clearVisionCapableModelsCache()
|
clearVisionCapableModelsCache()
|
||||||
;(modelAvailability.fetchAvailableModels as unknown as { mockRestore?: () => void }).mockRestore?.()
|
;(testCoerce<{ mockRestore?: () => void }>(modelAvailability.fetchAvailableModels)).mockRestore?.()
|
||||||
;(connectedProvidersCache.readConnectedProvidersCache as unknown as { mockRestore?: () => void }).mockRestore?.()
|
;(testCoerce<{ mockRestore?: () => void }>(connectedProvidersCache.readConnectedProvidersCache)).mockRestore?.()
|
||||||
})
|
})
|
||||||
|
|
||||||
test("returns configured multimodal-looker model when it already matches a vision-capable override", async () => {
|
test("returns configured multimodal-looker model when it already matches a vision-capable override", async () => {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ describe("pollSessionUntilIdle", () => {
|
|||||||
{ data: { ses_test: { type: "idle" } } },
|
{ data: { ses_test: { type: "idle" } } },
|
||||||
])
|
])
|
||||||
|
|
||||||
await pollSessionUntilIdle(client as any, "ses_test", { pollIntervalMs: 10, timeoutMs: 5000 })
|
await pollSessionUntilIdle(testCoerce(client), "ses_test", { pollIntervalMs: 10, timeoutMs: 5000 })
|
||||||
|
|
||||||
expect(client.session.status).toHaveBeenCalledTimes(3)
|
expect(client.session.status).toHaveBeenCalledTimes(3)
|
||||||
})
|
})
|
||||||
@@ -43,7 +43,7 @@ describe("pollSessionUntilIdle", () => {
|
|||||||
{ data: {} },
|
{ data: {} },
|
||||||
])
|
])
|
||||||
|
|
||||||
await pollSessionUntilIdle(client as any, "ses_test", { pollIntervalMs: 10, timeoutMs: 5000 })
|
await pollSessionUntilIdle(testCoerce(client), "ses_test", { pollIntervalMs: 10, timeoutMs: 5000 })
|
||||||
|
|
||||||
expect(client.session.status).toHaveBeenCalledTimes(1)
|
expect(client.session.status).toHaveBeenCalledTimes(1)
|
||||||
})
|
})
|
||||||
@@ -57,7 +57,7 @@ describe("pollSessionUntilIdle", () => {
|
|||||||
])
|
])
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
pollSessionUntilIdle(client as any, "ses_test", { pollIntervalMs: 10, timeoutMs: 50 })
|
pollSessionUntilIdle(testCoerce(client), "ses_test", { pollIntervalMs: 10, timeoutMs: 50 })
|
||||||
).rejects.toThrow("timed out")
|
).rejects.toThrow("timed out")
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ describe("pollSessionUntilIdle", () => {
|
|||||||
{ error: new Error("API error") },
|
{ error: new Error("API error") },
|
||||||
])
|
])
|
||||||
|
|
||||||
await pollSessionUntilIdle(client as any, "ses_test", { pollIntervalMs: 10, timeoutMs: 5000 })
|
await pollSessionUntilIdle(testCoerce(client), "ses_test", { pollIntervalMs: 10, timeoutMs: 5000 })
|
||||||
|
|
||||||
expect(client.session.status).toHaveBeenCalledTimes(1)
|
expect(client.session.status).toHaveBeenCalledTimes(1)
|
||||||
})
|
})
|
||||||
@@ -85,7 +85,7 @@ describe("pollSessionUntilIdle", () => {
|
|||||||
{ data: {} },
|
{ data: {} },
|
||||||
])
|
])
|
||||||
|
|
||||||
await pollSessionUntilIdle(client as any, "ses_test", { pollIntervalMs: 10, timeoutMs: 5000 })
|
await pollSessionUntilIdle(testCoerce(client), "ses_test", { pollIntervalMs: 10, timeoutMs: 5000 })
|
||||||
|
|
||||||
expect(client.session.status).toHaveBeenCalledTimes(4)
|
expect(client.session.status).toHaveBeenCalledTimes(4)
|
||||||
})
|
})
|
||||||
@@ -98,7 +98,7 @@ describe("pollSessionUntilIdle", () => {
|
|||||||
{ data: {} },
|
{ data: {} },
|
||||||
])
|
])
|
||||||
|
|
||||||
await pollSessionUntilIdle(client as any, "ses_test")
|
await pollSessionUntilIdle(testCoerce(client), "ses_test")
|
||||||
|
|
||||||
expect(client.session.status).toHaveBeenCalledTimes(1)
|
expect(client.session.status).toHaveBeenCalledTimes(1)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ describe("look-at tool", () => {
|
|||||||
// then should normalize to file_path
|
// then should normalize to file_path
|
||||||
test("normalizes path to file_path for LLM compatibility", () => {
|
test("normalizes path to file_path for LLM compatibility", () => {
|
||||||
const args = { path: "/some/file.png", goal: "analyze" }
|
const args = { path: "/some/file.png", goal: "analyze" }
|
||||||
const normalized = normalizeArgs(args as any)
|
const normalized = normalizeArgs(testCoerce(args))
|
||||||
expect(normalized.file_path).toBe("/some/file.png")
|
expect(normalized.file_path).toBe("/some/file.png")
|
||||||
expect(normalized.goal).toBe("analyze")
|
expect(normalized.goal).toBe("analyze")
|
||||||
})
|
})
|
||||||
@@ -33,7 +33,7 @@ describe("look-at tool", () => {
|
|||||||
// then prefer file_path
|
// then prefer file_path
|
||||||
test("prefers file_path over path when both provided", () => {
|
test("prefers file_path over path when both provided", () => {
|
||||||
const args = { file_path: "/preferred.png", path: "/fallback.png", goal: "test" }
|
const args = { file_path: "/preferred.png", path: "/fallback.png", goal: "test" }
|
||||||
const normalized = normalizeArgs(args as any)
|
const normalized = normalizeArgs(testCoerce(args))
|
||||||
expect(normalized.file_path).toBe("/preferred.png")
|
expect(normalized.file_path).toBe("/preferred.png")
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ describe("look-at tool", () => {
|
|||||||
// then preserve image_data in normalized args
|
// then preserve image_data in normalized args
|
||||||
test("preserves image_data when provided", () => {
|
test("preserves image_data when provided", () => {
|
||||||
const args = { image_data: "data:image/png;base64,iVBORw0KGgo=", goal: "analyze" }
|
const args = { image_data: "data:image/png;base64,iVBORw0KGgo=", goal: "analyze" }
|
||||||
const normalized = normalizeArgs(args as any)
|
const normalized = normalizeArgs(testCoerce(args))
|
||||||
expect(normalized.image_data).toBe("data:image/png;base64,iVBORw0KGgo=")
|
expect(normalized.image_data).toBe("data:image/png;base64,iVBORw0KGgo=")
|
||||||
expect(normalized.file_path).toBeUndefined()
|
expect(normalized.file_path).toBeUndefined()
|
||||||
})
|
})
|
||||||
@@ -69,7 +69,7 @@ describe("look-at tool", () => {
|
|||||||
// when validated
|
// when validated
|
||||||
// then clear error message
|
// then clear error message
|
||||||
test("returns error when neither file_path nor image_data provided", () => {
|
test("returns error when neither file_path nor image_data provided", () => {
|
||||||
const args = { goal: "analyze" } as any
|
const args = testCoerce({ goal: "analyze" })
|
||||||
const error = validateArgs(args)
|
const error = validateArgs(args)
|
||||||
expect(error).toContain("file_path")
|
expect(error).toContain("file_path")
|
||||||
expect(error).toContain("image_data")
|
expect(error).toContain("image_data")
|
||||||
@@ -88,7 +88,7 @@ describe("look-at tool", () => {
|
|||||||
// when validated
|
// when validated
|
||||||
// then clear error message
|
// then clear error message
|
||||||
test("returns error when goal is missing", () => {
|
test("returns error when goal is missing", () => {
|
||||||
const args = { file_path: "/some/path.png" } as any
|
const args = testCoerce({ file_path: "/some/path.png" })
|
||||||
const error = validateArgs(args)
|
const error = validateArgs(args)
|
||||||
expect(error).toContain("goal")
|
expect(error).toContain("goal")
|
||||||
expect(error).toContain("required")
|
expect(error).toContain("required")
|
||||||
@@ -156,10 +156,10 @@ describe("look-at tool", () => {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const tool = createLookAt({
|
const tool = createLookAt(testCoerce({
|
||||||
client: mockClient,
|
client: mockClient,
|
||||||
directory: "/project",
|
directory: "/project",
|
||||||
} as any)
|
}))
|
||||||
|
|
||||||
const toolContext: ToolContext = {
|
const toolContext: ToolContext = {
|
||||||
sessionID: "parent-session",
|
sessionID: "parent-session",
|
||||||
@@ -193,10 +193,10 @@ describe("look-at tool", () => {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const tool = createLookAt({
|
const tool = createLookAt(testCoerce({
|
||||||
client: mockClient,
|
client: mockClient,
|
||||||
directory: "/project",
|
directory: "/project",
|
||||||
} as any)
|
}))
|
||||||
|
|
||||||
const toolContext: ToolContext = {
|
const toolContext: ToolContext = {
|
||||||
sessionID: "parent-session",
|
sessionID: "parent-session",
|
||||||
@@ -230,10 +230,10 @@ describe("look-at tool", () => {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const tool = createLookAt({
|
const tool = createLookAt(testCoerce({
|
||||||
client: mockClient,
|
client: mockClient,
|
||||||
directory: "/project",
|
directory: "/project",
|
||||||
} as any)
|
}))
|
||||||
|
|
||||||
const toolContext: ToolContext = {
|
const toolContext: ToolContext = {
|
||||||
sessionID: "parent-session",
|
sessionID: "parent-session",
|
||||||
@@ -291,10 +291,10 @@ describe("look-at tool", () => {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const tool = createLookAt({
|
const tool = createLookAt(testCoerce({
|
||||||
client: mockClient,
|
client: mockClient,
|
||||||
directory: "/project",
|
directory: "/project",
|
||||||
} as any)
|
}))
|
||||||
|
|
||||||
const toolContext: ToolContext = {
|
const toolContext: ToolContext = {
|
||||||
sessionID: "parent-session",
|
sessionID: "parent-session",
|
||||||
@@ -346,10 +346,10 @@ describe("look-at tool", () => {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const tool = createLookAt({
|
const tool = createLookAt(testCoerce({
|
||||||
client: mockClient,
|
client: mockClient,
|
||||||
directory: "/project",
|
directory: "/project",
|
||||||
} as any)
|
}))
|
||||||
|
|
||||||
const toolContext: ToolContext = {
|
const toolContext: ToolContext = {
|
||||||
sessionID: "parent-session",
|
sessionID: "parent-session",
|
||||||
@@ -395,10 +395,10 @@ describe("look-at tool", () => {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const tool = createLookAt({
|
const tool = createLookAt(testCoerce({
|
||||||
client: mockClient,
|
client: mockClient,
|
||||||
directory: "/project",
|
directory: "/project",
|
||||||
} as any)
|
}))
|
||||||
|
|
||||||
const toolContext: ToolContext = {
|
const toolContext: ToolContext = {
|
||||||
sessionID: "parent-session",
|
sessionID: "parent-session",
|
||||||
@@ -437,10 +437,10 @@ describe("look-at tool", () => {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const tool = createLookAt({
|
const tool = createLookAt(testCoerce({
|
||||||
client: mockClient,
|
client: mockClient,
|
||||||
directory: "/project",
|
directory: "/project",
|
||||||
} as any)
|
}))
|
||||||
|
|
||||||
const toolContext: ToolContext = {
|
const toolContext: ToolContext = {
|
||||||
sessionID: "parent-session",
|
sessionID: "parent-session",
|
||||||
@@ -486,10 +486,10 @@ describe("look-at tool", () => {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const tool = createLookAt({
|
const tool = createLookAt(testCoerce({
|
||||||
client: mockClient,
|
client: mockClient,
|
||||||
directory: "/project",
|
directory: "/project",
|
||||||
} as any)
|
}))
|
||||||
|
|
||||||
const result = await tool.execute(
|
const result = await tool.execute(
|
||||||
{ file_path: "/test/file.png", goal: "analyze" },
|
{ file_path: "/test/file.png", goal: "analyze" },
|
||||||
@@ -515,10 +515,10 @@ describe("look-at tool", () => {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const tool = createLookAt({
|
const tool = createLookAt(testCoerce({
|
||||||
client: mockClient,
|
client: mockClient,
|
||||||
directory: "/project",
|
directory: "/project",
|
||||||
} as any)
|
}))
|
||||||
|
|
||||||
const result = await tool.execute(
|
const result = await tool.execute(
|
||||||
{ file_path: "/test/file.png", goal: "analyze" },
|
{ file_path: "/test/file.png", goal: "analyze" },
|
||||||
@@ -539,10 +539,10 @@ describe("look-at tool", () => {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const tool = createLookAt({
|
const tool = createLookAt(testCoerce({
|
||||||
client: mockClient,
|
client: mockClient,
|
||||||
directory: "/project",
|
directory: "/project",
|
||||||
} as any)
|
}))
|
||||||
|
|
||||||
const result = await tool.execute(
|
const result = await tool.execute(
|
||||||
{ file_path: "/test/file.png", goal: "analyze" },
|
{ file_path: "/test/file.png", goal: "analyze" },
|
||||||
@@ -579,10 +579,10 @@ describe("look-at tool", () => {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const tool = createLookAt({
|
const tool = createLookAt(testCoerce({
|
||||||
client: mockClient,
|
client: mockClient,
|
||||||
directory: "/project",
|
directory: "/project",
|
||||||
} as any)
|
}))
|
||||||
|
|
||||||
const toolContext: ToolContext = {
|
const toolContext: ToolContext = {
|
||||||
sessionID: "parent-session",
|
sessionID: "parent-session",
|
||||||
@@ -632,10 +632,10 @@ describe("look-at tool", () => {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const tool = createLookAt({
|
const tool = createLookAt(testCoerce({
|
||||||
client: mockClient,
|
client: mockClient,
|
||||||
directory: "/project",
|
directory: "/project",
|
||||||
} as any)
|
}))
|
||||||
|
|
||||||
const toolContext: ToolContext = {
|
const toolContext: ToolContext = {
|
||||||
sessionID: "parent-session",
|
sessionID: "parent-session",
|
||||||
@@ -701,10 +701,10 @@ describe("look-at tool", () => {
|
|||||||
test("instructs agent to analyze attached file when Read is disabled (file_path mode)", async () => {
|
test("instructs agent to analyze attached file when Read is disabled (file_path mode)", async () => {
|
||||||
const { mockClient, captured } = captureLastPromptBody()
|
const { mockClient, captured } = captureLastPromptBody()
|
||||||
|
|
||||||
const tool = createLookAt({
|
const tool = createLookAt(testCoerce({
|
||||||
client: mockClient,
|
client: mockClient,
|
||||||
directory: "/project",
|
directory: "/project",
|
||||||
} as any)
|
}))
|
||||||
|
|
||||||
await tool.execute(
|
await tool.execute(
|
||||||
{ file_path: "/test/file.png", goal: "describe contents" },
|
{ file_path: "/test/file.png", goal: "describe contents" },
|
||||||
@@ -726,10 +726,10 @@ describe("look-at tool", () => {
|
|||||||
test("instructs agent to analyze attached image when image_data is provided", async () => {
|
test("instructs agent to analyze attached image when image_data is provided", async () => {
|
||||||
const { mockClient, captured } = captureLastPromptBody()
|
const { mockClient, captured } = captureLastPromptBody()
|
||||||
|
|
||||||
const tool = createLookAt({
|
const tool = createLookAt(testCoerce({
|
||||||
client: mockClient,
|
client: mockClient,
|
||||||
directory: "/project",
|
directory: "/project",
|
||||||
} as any)
|
}))
|
||||||
|
|
||||||
await tool.execute(
|
await tool.execute(
|
||||||
{ image_data: "data:image/png;base64,iVBORw0KGgo=", goal: "describe image" },
|
{ image_data: "data:image/png;base64,iVBORw0KGgo=", goal: "describe image" },
|
||||||
@@ -751,10 +751,10 @@ describe("look-at tool", () => {
|
|||||||
test("explicitly warns the agent not to attempt Read when Read is disabled", async () => {
|
test("explicitly warns the agent not to attempt Read when Read is disabled", async () => {
|
||||||
const { mockClient, captured } = captureLastPromptBody()
|
const { mockClient, captured } = captureLastPromptBody()
|
||||||
|
|
||||||
const tool = createLookAt({
|
const tool = createLookAt(testCoerce({
|
||||||
client: mockClient,
|
client: mockClient,
|
||||||
directory: "/project",
|
directory: "/project",
|
||||||
} as any)
|
}))
|
||||||
|
|
||||||
await tool.execute(
|
await tool.execute(
|
||||||
{ file_path: "/test/file.pdf", goal: "extract text" },
|
{ file_path: "/test/file.pdf", goal: "extract text" },
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ describe("LSPClient", () => {
|
|||||||
const originalSetTimeout = globalThis.setTimeout
|
const originalSetTimeout = globalThis.setTimeout
|
||||||
globalThis.setTimeout = ((fn: (...args: unknown[]) => void, _ms?: number) => {
|
globalThis.setTimeout = ((fn: (...args: unknown[]) => void, _ms?: number) => {
|
||||||
fn()
|
fn()
|
||||||
return 0 as unknown as ReturnType<typeof setTimeout>
|
return testCoerce<ReturnType<typeof setTimeout>>(0)
|
||||||
}) as typeof setTimeout
|
}) as typeof setTimeout
|
||||||
|
|
||||||
const server: ResolvedServer = {
|
const server: ResolvedServer = {
|
||||||
@@ -50,7 +50,7 @@ describe("LSPClient", () => {
|
|||||||
|
|
||||||
// Stub protocol output: we only want to assert notifications.
|
// Stub protocol output: we only want to assert notifications.
|
||||||
const sendNotificationSpy = spyOn(
|
const sendNotificationSpy = spyOn(
|
||||||
client as unknown as { sendNotification: (m: string, p?: unknown) => void },
|
testCoerce<{ sendNotification: (m: string, p?: unknown) => void }>(client),
|
||||||
"sendNotification"
|
"sendNotification"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { spawn as bunSpawn } from "../../shared/bun-spawn-shim"
|
import { spawn as bunSpawn, type SpawnedProcess } from "../../shared/bun-spawn-shim"
|
||||||
import { spawn as nodeSpawn, type ChildProcess } from "node:child_process"
|
import { spawn as nodeSpawn, type ChildProcess } from "node:child_process"
|
||||||
import { existsSync, statSync } from "fs"
|
import { existsSync, statSync } from "fs"
|
||||||
import { log } from "../../shared/logger"
|
import { log } from "../../shared/logger"
|
||||||
@@ -127,6 +127,30 @@ function wrapNodeProcess(proc: ChildProcess): UnifiedProcess {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function wrapBunProcess(proc: SpawnedProcess): UnifiedProcess {
|
||||||
|
return {
|
||||||
|
stdin: {
|
||||||
|
write(chunk: Uint8Array | string) {
|
||||||
|
proc.stdin.write(chunk)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
stdout: {
|
||||||
|
getReader: () => proc.stdout.getReader(),
|
||||||
|
},
|
||||||
|
stderr: {
|
||||||
|
getReader: () => proc.stderr.getReader(),
|
||||||
|
},
|
||||||
|
get exitCode() {
|
||||||
|
return proc.exitCode
|
||||||
|
},
|
||||||
|
exited: proc.exited,
|
||||||
|
kill(signal?: string) {
|
||||||
|
proc.kill(signal === "SIGKILL" ? "SIGKILL" : undefined)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function spawnProcess(
|
export function spawnProcess(
|
||||||
command: string[],
|
command: string[],
|
||||||
options: { cwd: string; env: Record<string, string | undefined> }
|
options: { cwd: string; env: Record<string, string | undefined> }
|
||||||
@@ -154,5 +178,5 @@ export function spawnProcess(
|
|||||||
cwd: options.cwd,
|
cwd: options.cwd,
|
||||||
env: options.env,
|
env: options.env,
|
||||||
})
|
})
|
||||||
return proc as unknown as UnifiedProcess
|
return wrapBunProcess(proc)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -448,7 +448,7 @@ describe("session-manager storage - SDK path (beta mode)", () => {
|
|||||||
|
|
||||||
// Re-import to get fresh module with mocked isSqliteBackend
|
// Re-import to get fresh module with mocked isSqliteBackend
|
||||||
const { setStorageClient, getMainSessions } = await import("./storage")
|
const { setStorageClient, getMainSessions } = await import("./storage")
|
||||||
setStorageClient(mockClient as unknown as Parameters<typeof setStorageClient>[0])
|
setStorageClient(testCoerce<Parameters<typeof setStorageClient>[0]>(mockClient))
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const sessions = await getMainSessions({ directory: "/test" })
|
const sessions = await getMainSessions({ directory: "/test" })
|
||||||
@@ -473,7 +473,7 @@ describe("session-manager storage - SDK path (beta mode)", () => {
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
const { setStorageClient, getAllSessions } = await import("./storage")
|
const { setStorageClient, getAllSessions } = await import("./storage")
|
||||||
setStorageClient(mockClient as unknown as Parameters<typeof setStorageClient>[0])
|
setStorageClient(testCoerce<Parameters<typeof setStorageClient>[0]>(mockClient))
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const sessionIDs = await getAllSessions()
|
const sessionIDs = await getAllSessions()
|
||||||
@@ -503,7 +503,7 @@ describe("session-manager storage - SDK path (beta mode)", () => {
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
const { setStorageClient, readSessionMessages } = await import("./storage")
|
const { setStorageClient, readSessionMessages } = await import("./storage")
|
||||||
setStorageClient(mockClient as unknown as Parameters<typeof setStorageClient>[0])
|
setStorageClient(testCoerce<Parameters<typeof setStorageClient>[0]>(mockClient))
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const messages = await readSessionMessages("ses_test")
|
const messages = await readSessionMessages("ses_test")
|
||||||
@@ -531,7 +531,7 @@ describe("session-manager storage - SDK path (beta mode)", () => {
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
const { setStorageClient, readSessionTodos } = await import("./storage")
|
const { setStorageClient, readSessionTodos } = await import("./storage")
|
||||||
setStorageClient(mockClient as unknown as Parameters<typeof setStorageClient>[0])
|
setStorageClient(testCoerce<Parameters<typeof setStorageClient>[0]>(mockClient))
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const todos = await readSessionTodos("ses_test")
|
const todos = await readSessionTodos("ses_test")
|
||||||
@@ -555,7 +555,7 @@ describe("session-manager storage - SDK path (beta mode)", () => {
|
|||||||
}))
|
}))
|
||||||
|
|
||||||
const { setStorageClient, readSessionMessages } = await import("./storage")
|
const { setStorageClient, readSessionMessages } = await import("./storage")
|
||||||
setStorageClient(mockClient as unknown as Parameters<typeof setStorageClient>[0])
|
setStorageClient(testCoerce<Parameters<typeof setStorageClient>[0]>(mockClient))
|
||||||
|
|
||||||
await expect(readSessionMessages("ses_test")).rejects.toThrow("API error")
|
await expect(readSessionMessages("ses_test")).rejects.toThrow("API error")
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ describe("skill tool - agent restriction", () => {
|
|||||||
// given
|
// given
|
||||||
const loadedSkills = [createMockSkill("sisyphus-only-skill", { agent: "sisyphus" })]
|
const loadedSkills = [createMockSkill("sisyphus-only-skill", { agent: "sisyphus" })]
|
||||||
const tool = createSkillTool({ skills: loadedSkills })
|
const tool = createSkillTool({ skills: loadedSkills })
|
||||||
const contextWithoutAgent = { ...mockContext, agent: undefined as unknown as string }
|
const contextWithoutAgent = { ...mockContext, agent: testCoerce<string>(undefined) }
|
||||||
|
|
||||||
// when / #then
|
// when / #then
|
||||||
return expect(tool.execute({ name: "sisyphus-only-skill" }, contextWithoutAgent)).rejects.toThrow(
|
return expect(tool.execute({ name: "sisyphus-only-skill" }, contextWithoutAgent)).rejects.toThrow(
|
||||||
|
|||||||
Reference in New Issue
Block a user