test(features): 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:
@@ -134,7 +134,7 @@ Use \`background_output(task_id="<id>")\` to retrieve each result.
|
|||||||
const notification = buildBackgroundTaskNotificationText({
|
const notification = buildBackgroundTaskNotificationText({
|
||||||
task: {
|
task: {
|
||||||
id: "bg_abc123",
|
id: "bg_abc123",
|
||||||
description: undefined as unknown as string,
|
description: testCoerce<string>(undefined),
|
||||||
status: "completed",
|
status: "completed",
|
||||||
},
|
},
|
||||||
duration: "5s",
|
duration: "5s",
|
||||||
@@ -142,8 +142,8 @@ Use \`background_output(task_id="<id>")\` to retrieve each result.
|
|||||||
allComplete: true,
|
allComplete: true,
|
||||||
remainingCount: 0,
|
remainingCount: 0,
|
||||||
completedTasks: [
|
completedTasks: [
|
||||||
{ id: "bg_abc123", description: undefined as unknown as string, status: "completed" },
|
{ id: "bg_abc123", description: testCoerce<string>(undefined), status: "completed" },
|
||||||
{ id: "bg_def456", description: undefined as unknown as string, status: "completed" },
|
{ id: "bg_def456", description: testCoerce<string>(undefined), status: "completed" },
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -230,7 +230,7 @@ Use \`background_output(task_id="<id>")\` to retrieve each result.
|
|||||||
const notification = buildBackgroundTaskNotificationText({
|
const notification = buildBackgroundTaskNotificationText({
|
||||||
task: {
|
task: {
|
||||||
id: "bg_xyz789",
|
id: "bg_xyz789",
|
||||||
description: undefined as unknown as string,
|
description: testCoerce<string>(undefined),
|
||||||
status: "completed",
|
status: "completed",
|
||||||
},
|
},
|
||||||
duration: "3s",
|
duration: "3s",
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ describe("isCompactionAgent", () => {
|
|||||||
|
|
||||||
test("returns false for null", () => {
|
test("returns false for null", () => {
|
||||||
// when
|
// when
|
||||||
const result = isCompactionAgent(null as unknown as string)
|
const result = isCompactionAgent(testCoerce<string>(null))
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(result).toBe(false)
|
expect(result).toBe(false)
|
||||||
|
|||||||
@@ -16,12 +16,12 @@ function createManager(config?: BackgroundTaskConfig): BackgroundManager {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput, config: config })
|
const manager = new BackgroundManager({ pluginContext: testCoerce<PluginInput>({ client, directory: tmpdir() }), config: config })
|
||||||
const testManager = manager as unknown as {
|
const testManager = testCoerce<{
|
||||||
enqueueNotificationForParent: (sessionId: string, fn: () => Promise<void>) => Promise<void>
|
enqueueNotificationForParent: (sessionId: string, fn: () => Promise<void>) => Promise<void>
|
||||||
notifyParentSession: (task: BackgroundTask) => Promise<void>
|
notifyParentSession: (task: BackgroundTask) => Promise<void>
|
||||||
tasks: Map<string, BackgroundTask>
|
tasks: Map<string, BackgroundTask>
|
||||||
}
|
}>(manager)
|
||||||
|
|
||||||
testManager.enqueueNotificationForParent = async (_sessionId: string, fn) => {
|
testManager.enqueueNotificationForParent = async (_sessionId: string, fn) => {
|
||||||
await fn()
|
await fn()
|
||||||
@@ -32,7 +32,7 @@ function createManager(config?: BackgroundTaskConfig): BackgroundManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getTaskMap(manager: BackgroundManager): Map<string, BackgroundTask> {
|
function getTaskMap(manager: BackgroundManager): Map<string, BackgroundTask> {
|
||||||
return (manager as unknown as { tasks: Map<string, BackgroundTask> }).tasks
|
return (testCoerce<{ tasks: Map<string, BackgroundTask> }>(manager)).tasks
|
||||||
}
|
}
|
||||||
|
|
||||||
async function flushAsyncWork() {
|
async function flushAsyncWork() {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ describe("BackgroundManager session permission", () => {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
const directory = tmpdir()
|
const directory = tmpdir()
|
||||||
const manager = new BackgroundManager({ pluginContext: { client, directory } as unknown as PluginInput })
|
const manager = new BackgroundManager({ pluginContext: testCoerce<PluginInput>({ client, directory }) })
|
||||||
|
|
||||||
// when
|
// when
|
||||||
await manager.launch({
|
await manager.launch({
|
||||||
@@ -62,7 +62,7 @@ describe("BackgroundManager session permission", () => {
|
|||||||
abort: async () => ({}),
|
abort: async () => ({}),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
const manager = new BackgroundManager({ pluginContext: { client, directory: tmpdir() } as unknown as PluginInput })
|
const manager = new BackgroundManager({ pluginContext: testCoerce<PluginInput>({ client, directory: tmpdir() }) })
|
||||||
|
|
||||||
// when
|
// when
|
||||||
await manager.launch({
|
await manager.launch({
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ describe("verifySessionExists", () => {
|
|||||||
test("passes query directory to session lookup when provided", async () => {
|
test("passes query directory to session lookup when provided", async () => {
|
||||||
// given
|
// given
|
||||||
const get = mock(async () => ({ data: { id: "session-123" } }))
|
const get = mock(async () => ({ data: { id: "session-123" } }))
|
||||||
const client = {
|
const client = testCoerce<OpencodeClient>({
|
||||||
session: {
|
session: {
|
||||||
get,
|
get,
|
||||||
},
|
},
|
||||||
} as unknown as OpencodeClient
|
})
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result = await verifySessionExists(client, "session-123", "/project/root")
|
const result = await verifySessionExists(client, "session-123", "/project/root")
|
||||||
|
|||||||
@@ -20,14 +20,14 @@ describe("resolveSubagentSpawnContext", () => {
|
|||||||
test("passes query.directory to each session.get call", async () => {
|
test("passes query.directory to each session.get call", async () => {
|
||||||
// given
|
// given
|
||||||
const sessionGetCalls: Array<Record<string, unknown>> = []
|
const sessionGetCalls: Array<Record<string, unknown>> = []
|
||||||
const client = createMockClient((async (input) => {
|
const client = createMockClient(testCoerce<OpencodeClient["session"]["get"]>((async (input) => {
|
||||||
sessionGetCalls.push(input as Record<string, unknown>)
|
sessionGetCalls.push(input as Record<string, unknown>)
|
||||||
if (input.path.id === "child-session") {
|
if (input.path.id === "child-session") {
|
||||||
return { data: { id: "child-session", parentID: "root-session" } }
|
return { data: { id: "child-session", parentID: "root-session" } }
|
||||||
}
|
}
|
||||||
|
|
||||||
return { data: { id: "root-session", parentID: undefined } }
|
return { data: { id: "root-session", parentID: undefined } }
|
||||||
}) as unknown as OpencodeClient["session"]["get"])
|
})))
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result = await resolveSubagentSpawnContext(client, "child-session", "/project/root")
|
const result = await resolveSubagentSpawnContext(client, "child-session", "/project/root")
|
||||||
@@ -50,10 +50,10 @@ describe("resolveSubagentSpawnContext", () => {
|
|||||||
describe("#given session.get returns an SDK error response", () => {
|
describe("#given session.get returns an SDK error response", () => {
|
||||||
test("throws a fail-closed spawn blocked error", async () => {
|
test("throws a fail-closed spawn blocked error", async () => {
|
||||||
// given
|
// given
|
||||||
const client = createMockClient((async () => ({
|
const client = createMockClient(testCoerce<OpencodeClient["session"]["get"]>((async () => ({
|
||||||
error: "lookup failed",
|
error: "lookup failed",
|
||||||
data: undefined,
|
data: undefined,
|
||||||
})) as unknown as OpencodeClient["session"]["get"])
|
}))))
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result = resolveSubagentSpawnContext(client, "parent-session")
|
const result = resolveSubagentSpawnContext(client, "parent-session")
|
||||||
@@ -66,9 +66,9 @@ describe("resolveSubagentSpawnContext", () => {
|
|||||||
describe("#given session.get returns no session data", () => {
|
describe("#given session.get returns no session data", () => {
|
||||||
test("throws a fail-closed spawn blocked error", async () => {
|
test("throws a fail-closed spawn blocked error", async () => {
|
||||||
// given
|
// given
|
||||||
const client = createMockClient((async () => ({
|
const client = createMockClient(testCoerce<OpencodeClient["session"]["get"]>((async () => ({
|
||||||
data: undefined,
|
data: undefined,
|
||||||
})) as unknown as OpencodeClient["session"]["get"])
|
}))))
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result = resolveSubagentSpawnContext(client, "parent-session")
|
const result = resolveSubagentSpawnContext(client, "parent-session")
|
||||||
@@ -81,12 +81,12 @@ describe("resolveSubagentSpawnContext", () => {
|
|||||||
describe("depth calculation smoke tests (regression guard)", () => {
|
describe("depth calculation smoke tests (regression guard)", () => {
|
||||||
test("root session (no parentID) reports depth 0 and childDepth 1", async () => {
|
test("root session (no parentID) reports depth 0 and childDepth 1", async () => {
|
||||||
// given - a root session with no parent
|
// given - a root session with no parent
|
||||||
const client = createMockClient((async (opts) => {
|
const client = createMockClient(testCoerce<OpencodeClient["session"]["get"]>((async (opts) => {
|
||||||
if (opts.path.id === "root-session") {
|
if (opts.path.id === "root-session") {
|
||||||
return { data: { id: "root-session", parentID: undefined } }
|
return { data: { id: "root-session", parentID: undefined } }
|
||||||
}
|
}
|
||||||
return { error: "not found", data: undefined }
|
return { error: "not found", data: undefined }
|
||||||
}) as unknown as OpencodeClient["session"]["get"])
|
})))
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result = await resolveSubagentSpawnContext(client, "root-session")
|
const result = await resolveSubagentSpawnContext(client, "root-session")
|
||||||
@@ -99,7 +99,7 @@ describe("resolveSubagentSpawnContext", () => {
|
|||||||
|
|
||||||
test("depth-1 child reports childDepth 2", async () => {
|
test("depth-1 child reports childDepth 2", async () => {
|
||||||
// given - child -> root chain
|
// given - child -> root chain
|
||||||
const client = createMockClient((async (opts) => {
|
const client = createMockClient(testCoerce<OpencodeClient["session"]["get"]>((async (opts) => {
|
||||||
if (opts.path.id === "child-1") {
|
if (opts.path.id === "child-1") {
|
||||||
return { data: { id: "child-1", parentID: "root-session" } }
|
return { data: { id: "child-1", parentID: "root-session" } }
|
||||||
}
|
}
|
||||||
@@ -107,7 +107,7 @@ describe("resolveSubagentSpawnContext", () => {
|
|||||||
return { data: { id: "root-session", parentID: undefined } }
|
return { data: { id: "root-session", parentID: undefined } }
|
||||||
}
|
}
|
||||||
return { error: "not found", data: undefined }
|
return { error: "not found", data: undefined }
|
||||||
}) as unknown as OpencodeClient["session"]["get"])
|
})))
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result = await resolveSubagentSpawnContext(client, "child-1")
|
const result = await resolveSubagentSpawnContext(client, "child-1")
|
||||||
@@ -120,7 +120,7 @@ describe("resolveSubagentSpawnContext", () => {
|
|||||||
|
|
||||||
test("depth-2 grandchild reports childDepth 3", async () => {
|
test("depth-2 grandchild reports childDepth 3", async () => {
|
||||||
// given - grandchild -> child -> root chain
|
// given - grandchild -> child -> root chain
|
||||||
const client = createMockClient((async (opts) => {
|
const client = createMockClient(testCoerce<OpencodeClient["session"]["get"]>((async (opts) => {
|
||||||
const sessions: Record<string, { id: string; parentID?: string }> = {
|
const sessions: Record<string, { id: string; parentID?: string }> = {
|
||||||
"grandchild": { id: "grandchild", parentID: "child" },
|
"grandchild": { id: "grandchild", parentID: "child" },
|
||||||
"child": { id: "child", parentID: "root" },
|
"child": { id: "child", parentID: "root" },
|
||||||
@@ -129,7 +129,7 @@ describe("resolveSubagentSpawnContext", () => {
|
|||||||
const session = sessions[opts.path.id]
|
const session = sessions[opts.path.id]
|
||||||
if (session) return { data: session }
|
if (session) return { data: session }
|
||||||
return { error: "not found", data: undefined }
|
return { error: "not found", data: undefined }
|
||||||
}) as unknown as OpencodeClient["session"]["get"])
|
})))
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result = await resolveSubagentSpawnContext(client, "grandchild")
|
const result = await resolveSubagentSpawnContext(client, "grandchild")
|
||||||
@@ -153,11 +153,11 @@ describe("resolveSubagentSpawnContext", () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const client = createMockClient((async (opts) => {
|
const client = createMockClient(testCoerce<OpencodeClient["session"]["get"]>((async (opts) => {
|
||||||
const session = sessions[opts.path.id]
|
const session = sessions[opts.path.id]
|
||||||
if (session) return { data: session }
|
if (session) return { data: session }
|
||||||
return { error: "not found", data: undefined }
|
return { error: "not found", data: undefined }
|
||||||
}) as unknown as OpencodeClient["session"]["get"])
|
})))
|
||||||
|
|
||||||
// when - resolve from the deepest session
|
// when - resolve from the deepest session
|
||||||
const deepest = `session-${DEFAULT_MAX_SUBAGENT_DEPTH}`
|
const deepest = `session-${DEFAULT_MAX_SUBAGENT_DEPTH}`
|
||||||
@@ -170,7 +170,7 @@ describe("resolveSubagentSpawnContext", () => {
|
|||||||
|
|
||||||
test("detects parent cycle and throws", async () => {
|
test("detects parent cycle and throws", async () => {
|
||||||
// given - A -> B -> A (cycle)
|
// given - A -> B -> A (cycle)
|
||||||
const client = createMockClient((async (opts) => {
|
const client = createMockClient(testCoerce<OpencodeClient["session"]["get"]>((async (opts) => {
|
||||||
const sessions: Record<string, { id: string; parentID?: string }> = {
|
const sessions: Record<string, { id: string; parentID?: string }> = {
|
||||||
"session-a": { id: "session-a", parentID: "session-b" },
|
"session-a": { id: "session-a", parentID: "session-b" },
|
||||||
"session-b": { id: "session-b", parentID: "session-a" },
|
"session-b": { id: "session-b", parentID: "session-a" },
|
||||||
@@ -178,7 +178,7 @@ describe("resolveSubagentSpawnContext", () => {
|
|||||||
const session = sessions[opts.path.id]
|
const session = sessions[opts.path.id]
|
||||||
if (session) return { data: session }
|
if (session) return { data: session }
|
||||||
return { error: "not found", data: undefined }
|
return { error: "not found", data: undefined }
|
||||||
}) as unknown as OpencodeClient["session"]["get"])
|
})))
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result = resolveSubagentSpawnContext(client, "session-a")
|
const result = resolveSubagentSpawnContext(client, "session-a")
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ describe("createContextInjectorMessagesTransformHook", () => {
|
|||||||
createMockMessage("user", "Second message", sessionID),
|
createMockMessage("user", "Second message", sessionID),
|
||||||
]
|
]
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const output = { messages } as any
|
const output = testCoerce({ messages })
|
||||||
|
|
||||||
// when
|
// when
|
||||||
await hook["experimental.chat.messages.transform"]!({}, output)
|
await hook["experimental.chat.messages.transform"]!({}, output)
|
||||||
@@ -115,7 +115,7 @@ describe("createContextInjectorMessagesTransformHook", () => {
|
|||||||
const sessionID = "ses_transform2"
|
const sessionID = "ses_transform2"
|
||||||
const messages = [createMockMessage("user", "Hello world", sessionID)]
|
const messages = [createMockMessage("user", "Hello world", sessionID)]
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const output = { messages } as any
|
const output = testCoerce({ messages })
|
||||||
|
|
||||||
// when
|
// when
|
||||||
await hook["experimental.chat.messages.transform"]!({}, output)
|
await hook["experimental.chat.messages.transform"]!({}, output)
|
||||||
@@ -135,7 +135,7 @@ describe("createContextInjectorMessagesTransformHook", () => {
|
|||||||
})
|
})
|
||||||
const messages = [createMockMessage("assistant", "Response", sessionID)]
|
const messages = [createMockMessage("assistant", "Response", sessionID)]
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const output = { messages } as any
|
const output = testCoerce({ messages })
|
||||||
|
|
||||||
// when
|
// when
|
||||||
await hook["experimental.chat.messages.transform"]!({}, output)
|
await hook["experimental.chat.messages.transform"]!({}, output)
|
||||||
@@ -156,7 +156,7 @@ describe("createContextInjectorMessagesTransformHook", () => {
|
|||||||
})
|
})
|
||||||
const messages = [createMockMessage("user", "Message", sessionID)]
|
const messages = [createMockMessage("user", "Message", sessionID)]
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const output = { messages } as any
|
const output = testCoerce({ messages })
|
||||||
|
|
||||||
// when
|
// when
|
||||||
await hook["experimental.chat.messages.transform"]!({}, output)
|
await hook["experimental.chat.messages.transform"]!({}, output)
|
||||||
|
|||||||
@@ -79,6 +79,14 @@ type MessagesTransformHook = {
|
|||||||
) => Promise<void>
|
) => Promise<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getSessionIDFromMessageInfo(info: Message): string | undefined {
|
||||||
|
return "sessionID" in info && typeof info.sessionID === "string" ? info.sessionID : undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasText(part: Part): boolean {
|
||||||
|
return "text" in part && typeof part.text === "string" && part.text.length > 0
|
||||||
|
}
|
||||||
|
|
||||||
export function createContextInjectorMessagesTransformHook(
|
export function createContextInjectorMessagesTransformHook(
|
||||||
collector: ContextCollector
|
collector: ContextCollector
|
||||||
): MessagesTransformHook {
|
): MessagesTransformHook {
|
||||||
@@ -106,8 +114,7 @@ export function createContextInjectorMessagesTransformHook(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const lastUserMessage = messages[lastUserMessageIndex]
|
const lastUserMessage = messages[lastUserMessageIndex]
|
||||||
// Try message.info.sessionID first, fallback to mainSessionID
|
const messageSessionID = getSessionIDFromMessageInfo(lastUserMessage.info)
|
||||||
const messageSessionID = (lastUserMessage.info as unknown as { sessionID?: string }).sessionID
|
|
||||||
const sessionID = messageSessionID ?? getMainSessionID()
|
const sessionID = messageSessionID ?? getMainSessionID()
|
||||||
log("[DEBUG] Extracted sessionID", {
|
log("[DEBUG] Extracted sessionID", {
|
||||||
messageSessionID,
|
messageSessionID,
|
||||||
@@ -135,7 +142,7 @@ export function createContextInjectorMessagesTransformHook(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const textPartIndex = lastUserMessage.parts.findIndex(
|
const textPartIndex = lastUserMessage.parts.findIndex(
|
||||||
(p) => p.type === "text" && (p as { text?: string }).text
|
(p) => p.type === "text" && hasText(p)
|
||||||
)
|
)
|
||||||
|
|
||||||
if (textPartIndex === -1) {
|
if (textPartIndex === -1) {
|
||||||
@@ -150,7 +157,7 @@ export function createContextInjectorMessagesTransformHook(
|
|||||||
const syntheticPart = {
|
const syntheticPart = {
|
||||||
id: `synthetic_hook_${sessionID}`,
|
id: `synthetic_hook_${sessionID}`,
|
||||||
messageID: lastUserMessage.info.id,
|
messageID: lastUserMessage.info.id,
|
||||||
sessionID: (lastUserMessage.info as { sessionID?: string }).sessionID ?? "",
|
sessionID: messageSessionID ?? "",
|
||||||
type: "text" as const,
|
type: "text" as const,
|
||||||
text: pending.merged,
|
text: pending.merged,
|
||||||
synthetic: true, // hidden in UI
|
synthetic: true, // hidden in UI
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => {
|
|||||||
{ info: { agent: "sisyphus", model: { providerID: "anthropic", modelID: "claude-opus-4" } } },
|
{ info: { agent: "sisyphus", model: { providerID: "anthropic", modelID: "claude-opus-4" } } },
|
||||||
])
|
])
|
||||||
|
|
||||||
const result = await findNearestMessageWithFieldsFromSDK(mockClient as any, "ses_123")
|
const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123")
|
||||||
|
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
agent: "sisyphus",
|
agent: "sisyphus",
|
||||||
@@ -87,7 +87,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => {
|
|||||||
{ info: { agent: "sisyphus", providerID: "openai", modelID: "gpt-5" } },
|
{ info: { agent: "sisyphus", providerID: "openai", modelID: "gpt-5" } },
|
||||||
])
|
])
|
||||||
|
|
||||||
const result = await findNearestMessageWithFieldsFromSDK(mockClient as any, "ses_123")
|
const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123")
|
||||||
|
|
||||||
expect(result).toEqual({
|
expect(result).toEqual({
|
||||||
agent: "sisyphus",
|
agent: "sisyphus",
|
||||||
@@ -102,7 +102,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => {
|
|||||||
{ id: "msg_new", info: { agent: "new-agent", model: { providerID: "new", modelID: "model" }, time: { created: 20 } } },
|
{ id: "msg_new", info: { agent: "new-agent", model: { providerID: "new", modelID: "model" }, time: { created: 20 } } },
|
||||||
])
|
])
|
||||||
|
|
||||||
const result = await findNearestMessageWithFieldsFromSDK(mockClient as any, "ses_123")
|
const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123")
|
||||||
|
|
||||||
expect(result?.agent).toBe("new-agent")
|
expect(result?.agent).toBe("new-agent")
|
||||||
})
|
})
|
||||||
@@ -112,7 +112,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => {
|
|||||||
{ info: { agent: "partial-agent" } },
|
{ info: { agent: "partial-agent" } },
|
||||||
])
|
])
|
||||||
|
|
||||||
const result = await findNearestMessageWithFieldsFromSDK(mockClient as any, "ses_123")
|
const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123")
|
||||||
|
|
||||||
expect(result?.agent).toBe("partial-agent")
|
expect(result?.agent).toBe("partial-agent")
|
||||||
})
|
})
|
||||||
@@ -123,7 +123,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => {
|
|||||||
{ info: {} },
|
{ info: {} },
|
||||||
])
|
])
|
||||||
|
|
||||||
const result = await findNearestMessageWithFieldsFromSDK(mockClient as any, "ses_123")
|
const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123")
|
||||||
|
|
||||||
expect(result).toBeNull()
|
expect(result).toBeNull()
|
||||||
})
|
})
|
||||||
@@ -131,7 +131,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => {
|
|||||||
it("returns null when messages array is empty", async () => {
|
it("returns null when messages array is empty", async () => {
|
||||||
const mockClient = createMockClient([])
|
const mockClient = createMockClient([])
|
||||||
|
|
||||||
const result = await findNearestMessageWithFieldsFromSDK(mockClient as any, "ses_123")
|
const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123")
|
||||||
|
|
||||||
expect(result).toBeNull()
|
expect(result).toBeNull()
|
||||||
})
|
})
|
||||||
@@ -145,7 +145,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await findNearestMessageWithFieldsFromSDK(mockClient as any, "ses_123")
|
const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123")
|
||||||
|
|
||||||
expect(result).toBeNull()
|
expect(result).toBeNull()
|
||||||
})
|
})
|
||||||
@@ -161,7 +161,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => {
|
|||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
const result = await findNearestMessageWithFieldsFromSDK(mockClient as any, "ses_123")
|
const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123")
|
||||||
|
|
||||||
expect(result?.tools).toEqual({ edit: true, write: false })
|
expect(result?.tools).toEqual({ edit: true, write: false })
|
||||||
})
|
})
|
||||||
@@ -172,7 +172,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => {
|
|||||||
{ id: "msg_older", info: { agent: "newest-by-time", model: { providerID: "openai", modelID: "gpt-5" }, time: { created: 100 } } },
|
{ id: "msg_older", info: { agent: "newest-by-time", model: { providerID: "openai", modelID: "gpt-5" }, time: { created: 100 } } },
|
||||||
])
|
])
|
||||||
|
|
||||||
const result = await findNearestMessageWithFieldsFromSDK(mockClient as any, "ses_123")
|
const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123")
|
||||||
|
|
||||||
expect(result?.agent).toBe("newest-by-time")
|
expect(result?.agent).toBe("newest-by-time")
|
||||||
})
|
})
|
||||||
@@ -190,7 +190,7 @@ describe("findNearestMessageWithFieldsFromSDK", () => {
|
|||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
const result = await findNearestMessageWithFieldsFromSDK(mockClient as any, "ses_123")
|
const result = await findNearestMessageWithFieldsFromSDK(testCoerce(mockClient), "ses_123")
|
||||||
|
|
||||||
expect(result?.agent).toBe("sisyphus")
|
expect(result?.agent).toBe("sisyphus")
|
||||||
})
|
})
|
||||||
@@ -252,7 +252,7 @@ describe("findFirstMessageWithAgentFromSDK", () => {
|
|||||||
{ info: { agent: "second-agent" } },
|
{ info: { agent: "second-agent" } },
|
||||||
])
|
])
|
||||||
|
|
||||||
const result = await findFirstMessageWithAgentFromSDK(mockClient as any, "ses_123")
|
const result = await findFirstMessageWithAgentFromSDK(testCoerce(mockClient), "ses_123")
|
||||||
|
|
||||||
expect(result).toBe("first-agent")
|
expect(result).toBe("first-agent")
|
||||||
})
|
})
|
||||||
@@ -263,7 +263,7 @@ describe("findFirstMessageWithAgentFromSDK", () => {
|
|||||||
{ id: "msg_early", info: { agent: "earliest-agent", time: { created: 10 } } },
|
{ id: "msg_early", info: { agent: "earliest-agent", time: { created: 10 } } },
|
||||||
])
|
])
|
||||||
|
|
||||||
const result = await findFirstMessageWithAgentFromSDK(mockClient as any, "ses_123")
|
const result = await findFirstMessageWithAgentFromSDK(testCoerce(mockClient), "ses_123")
|
||||||
|
|
||||||
expect(result).toBe("earliest-agent")
|
expect(result).toBe("earliest-agent")
|
||||||
})
|
})
|
||||||
@@ -274,7 +274,7 @@ describe("findFirstMessageWithAgentFromSDK", () => {
|
|||||||
{ id: "msg_real", info: { agent: "sisyphus", time: { created: 20 } } },
|
{ id: "msg_real", info: { agent: "sisyphus", time: { created: 20 } } },
|
||||||
])
|
])
|
||||||
|
|
||||||
const result = await findFirstMessageWithAgentFromSDK(mockClient as any, "ses_123")
|
const result = await findFirstMessageWithAgentFromSDK(testCoerce(mockClient), "ses_123")
|
||||||
|
|
||||||
expect(result).toBe("sisyphus")
|
expect(result).toBe("sisyphus")
|
||||||
})
|
})
|
||||||
@@ -285,7 +285,7 @@ describe("findFirstMessageWithAgentFromSDK", () => {
|
|||||||
{ info: { agent: "first-real-agent" } },
|
{ info: { agent: "first-real-agent" } },
|
||||||
])
|
])
|
||||||
|
|
||||||
const result = await findFirstMessageWithAgentFromSDK(mockClient as any, "ses_123")
|
const result = await findFirstMessageWithAgentFromSDK(testCoerce(mockClient), "ses_123")
|
||||||
|
|
||||||
expect(result).toBe("first-real-agent")
|
expect(result).toBe("first-real-agent")
|
||||||
})
|
})
|
||||||
@@ -296,7 +296,7 @@ describe("findFirstMessageWithAgentFromSDK", () => {
|
|||||||
{ info: {} },
|
{ info: {} },
|
||||||
])
|
])
|
||||||
|
|
||||||
const result = await findFirstMessageWithAgentFromSDK(mockClient as any, "ses_123")
|
const result = await findFirstMessageWithAgentFromSDK(testCoerce(mockClient), "ses_123")
|
||||||
|
|
||||||
expect(result).toBeNull()
|
expect(result).toBeNull()
|
||||||
})
|
})
|
||||||
@@ -310,7 +310,7 @@ describe("findFirstMessageWithAgentFromSDK", () => {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await findFirstMessageWithAgentFromSDK(mockClient as any, "ses_123")
|
const result = await findFirstMessageWithAgentFromSDK(testCoerce(mockClient), "ses_123")
|
||||||
|
|
||||||
expect(result).toBeNull()
|
expect(result).toBeNull()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -634,7 +634,7 @@ describe("SkillMcpManager", () => {
|
|||||||
close: mock(() => Promise.resolve()),
|
close: mock(() => Promise.resolve()),
|
||||||
}
|
}
|
||||||
|
|
||||||
const getOrCreateSpy = spyOn(manager as any, "getOrCreateClientWithRetry")
|
const getOrCreateSpy = spyOn(testCoerce(manager), "getOrCreateClientWithRetry")
|
||||||
getOrCreateSpy.mockResolvedValue(mockClient)
|
getOrCreateSpy.mockResolvedValue(mockClient)
|
||||||
|
|
||||||
// when
|
// when
|
||||||
@@ -668,7 +668,7 @@ describe("SkillMcpManager", () => {
|
|||||||
close: mock(() => Promise.resolve()),
|
close: mock(() => Promise.resolve()),
|
||||||
}
|
}
|
||||||
|
|
||||||
const getOrCreateSpy = spyOn(manager as any, "getOrCreateClientWithRetry")
|
const getOrCreateSpy = spyOn(testCoerce(manager), "getOrCreateClientWithRetry")
|
||||||
getOrCreateSpy.mockResolvedValue(mockClient)
|
getOrCreateSpy.mockResolvedValue(mockClient)
|
||||||
|
|
||||||
// when / #then
|
// when / #then
|
||||||
@@ -700,7 +700,7 @@ describe("SkillMcpManager", () => {
|
|||||||
close: mock(() => Promise.resolve()),
|
close: mock(() => Promise.resolve()),
|
||||||
}
|
}
|
||||||
|
|
||||||
const getOrCreateSpy = spyOn(manager as any, "getOrCreateClientWithRetry")
|
const getOrCreateSpy = spyOn(testCoerce(manager), "getOrCreateClientWithRetry")
|
||||||
getOrCreateSpy.mockResolvedValue(mockClient)
|
getOrCreateSpy.mockResolvedValue(mockClient)
|
||||||
|
|
||||||
// when / #then
|
// when / #then
|
||||||
@@ -929,7 +929,7 @@ describe("SkillMcpManager", () => {
|
|||||||
close: mock(() => Promise.resolve()),
|
close: mock(() => Promise.resolve()),
|
||||||
}
|
}
|
||||||
|
|
||||||
const getOrCreateSpy = spyOn(manager as any, "getOrCreateClientWithRetry")
|
const getOrCreateSpy = spyOn(testCoerce(manager), "getOrCreateClientWithRetry")
|
||||||
getOrCreateSpy.mockResolvedValue(mockClient)
|
getOrCreateSpy.mockResolvedValue(mockClient)
|
||||||
|
|
||||||
// when
|
// when
|
||||||
@@ -962,7 +962,7 @@ describe("SkillMcpManager", () => {
|
|||||||
close: mock(() => Promise.resolve()),
|
close: mock(() => Promise.resolve()),
|
||||||
}
|
}
|
||||||
|
|
||||||
const getOrCreateSpy = spyOn(manager as any, "getOrCreateClientWithRetry")
|
const getOrCreateSpy = spyOn(testCoerce(manager), "getOrCreateClientWithRetry")
|
||||||
getOrCreateSpy.mockResolvedValue(mockClient)
|
getOrCreateSpy.mockResolvedValue(mockClient)
|
||||||
|
|
||||||
// when / #then
|
// when / #then
|
||||||
|
|||||||
@@ -20,15 +20,15 @@ describe("TaskToastManager", () => {
|
|||||||
showToast: mock(() => Promise.resolve()),
|
showToast: mock(() => Promise.resolve()),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
mockConcurrencyManager = {
|
mockConcurrencyManager = testCoerce<ConcurrencyManager>({
|
||||||
getConcurrencyLimit: mock(() => 5),
|
getConcurrencyLimit: mock(() => 5),
|
||||||
} as unknown as ConcurrencyManager
|
})
|
||||||
|
|
||||||
const mod = await import("./manager")
|
const mod = await import("./manager")
|
||||||
TaskToastManager = mod.TaskToastManager
|
TaskToastManager = mod.TaskToastManager
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
toastManager = new TaskToastManager(mockClient as any, mockConcurrencyManager)
|
toastManager = new TaskToastManager(testCoerce(mockClient), mockConcurrencyManager)
|
||||||
})
|
})
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -108,14 +108,14 @@ describe("TaskToastManager", () => {
|
|||||||
|
|
||||||
test("should display concurrency limit info when available", () => {
|
test("should display concurrency limit info when available", () => {
|
||||||
// given - a concurrency manager with known limit
|
// given - a concurrency manager with known limit
|
||||||
const mockConcurrencyWithCounts = {
|
const mockConcurrencyWithCounts = testCoerce<ConcurrencyManager>({
|
||||||
getConcurrencyLimit: mock(() => 5),
|
getConcurrencyLimit: mock(() => 5),
|
||||||
getRunningCount: mock(() => 2),
|
getRunningCount: mock(() => 2),
|
||||||
getQueuedCount: mock(() => 1),
|
getQueuedCount: mock(() => 1),
|
||||||
} as unknown as ConcurrencyManager
|
})
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const managerWithConcurrency = new TaskToastManager(mockClient as any, mockConcurrencyWithCounts)
|
const managerWithConcurrency = new TaskToastManager(testCoerce(mockClient), mockConcurrencyWithCounts)
|
||||||
|
|
||||||
// when - a task is added
|
// when - a task is added
|
||||||
managerWithConcurrency.addTask({
|
managerWithConcurrency.addTask({
|
||||||
@@ -357,11 +357,11 @@ describe("TaskToastManager", () => {
|
|||||||
|
|
||||||
test("should show model name in queued tasks too", () => {
|
test("should show model name in queued tasks too", () => {
|
||||||
// given - a concurrency manager that limits to 1
|
// given - a concurrency manager that limits to 1
|
||||||
const limitedConcurrency = {
|
const limitedConcurrency = testCoerce<ConcurrencyManager>({
|
||||||
getConcurrencyLimit: mock(() => 1),
|
getConcurrencyLimit: mock(() => 1),
|
||||||
} as unknown as ConcurrencyManager
|
})
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const limitedManager = new TaskToastManager(mockClient as any, limitedConcurrency)
|
const limitedManager = new TaskToastManager(testCoerce(mockClient), limitedConcurrency)
|
||||||
|
|
||||||
limitedManager.addTask({
|
limitedManager.addTask({
|
||||||
id: "task_running",
|
id: "task_running",
|
||||||
|
|||||||
@@ -41,9 +41,9 @@ function createRuntimeState(teamRunId: string): RuntimeState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function createStubBgMgr(): BackgroundManager {
|
function createStubBgMgr(): BackgroundManager {
|
||||||
return {
|
return testCoerce<BackgroundManager>({
|
||||||
cancelTask: async () => undefined,
|
cancelTask: async () => undefined,
|
||||||
} as unknown as BackgroundManager
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
describe("cleanupTeamRunResources", () => {
|
describe("cleanupTeamRunResources", () => {
|
||||||
|
|||||||
@@ -39,15 +39,15 @@ describe("TmuxPollingManager overlap", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const manager = new TmuxPollingManager(
|
const manager = new TmuxPollingManager(
|
||||||
client as unknown as import("../../tools/delegate-task/types").OpencodeClient,
|
testCoerce<import("../../tools/delegate-task/types").OpencodeClient>(client),
|
||||||
sessions,
|
sessions,
|
||||||
async () => {},
|
async () => {},
|
||||||
)
|
)
|
||||||
|
|
||||||
//#when
|
//#when
|
||||||
const firstPoll = (manager as unknown as { pollSessions: () => Promise<void> }).pollSessions()
|
const firstPoll = (testCoerce<{ pollSessions: () => Promise<void> }>(manager)).pollSessions()
|
||||||
await Promise.resolve()
|
await Promise.resolve()
|
||||||
const secondPoll = (manager as unknown as { pollSessions: () => Promise<void> }).pollSessions()
|
const secondPoll = (testCoerce<{ pollSessions: () => Promise<void> }>(manager)).pollSessions()
|
||||||
releaseStatus?.()
|
releaseStatus?.()
|
||||||
await Promise.all([firstPoll, secondPoll])
|
await Promise.all([firstPoll, secondPoll])
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ describe("TmuxPollingManager overlap", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const manager = new TmuxPollingManager(
|
const manager = new TmuxPollingManager(
|
||||||
client as unknown as import("../../tools/delegate-task/types").OpencodeClient,
|
testCoerce<import("../../tools/delegate-task/types").OpencodeClient>(client),
|
||||||
sessions,
|
sessions,
|
||||||
async (sessionId) => {
|
async (sessionId) => {
|
||||||
closedSessionIds.push(sessionId)
|
closedSessionIds.push(sessionId)
|
||||||
@@ -98,7 +98,7 @@ describe("TmuxPollingManager overlap", () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
//#when
|
//#when
|
||||||
const pollSessions = (manager as unknown as { pollSessions: () => Promise<void> }).pollSessions
|
const pollSessions = (testCoerce<{ pollSessions: () => Promise<void> }>(manager)).pollSessions
|
||||||
await pollSessions.call(manager)
|
await pollSessions.call(manager)
|
||||||
await pollSessions.call(manager)
|
await pollSessions.call(manager)
|
||||||
await pollSessions.call(manager)
|
await pollSessions.call(manager)
|
||||||
@@ -132,7 +132,7 @@ describe("TmuxPollingManager overlap", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const manager = new TmuxPollingManager(
|
const manager = new TmuxPollingManager(
|
||||||
client as unknown as import("../../tools/delegate-task/types").OpencodeClient,
|
testCoerce<import("../../tools/delegate-task/types").OpencodeClient>(client),
|
||||||
sessions,
|
sessions,
|
||||||
async (sessionId) => {
|
async (sessionId) => {
|
||||||
closedSessionIds.push(sessionId)
|
closedSessionIds.push(sessionId)
|
||||||
@@ -140,7 +140,7 @@ describe("TmuxPollingManager overlap", () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const pollSessions = (manager as unknown as { pollSessions: () => Promise<void> }).pollSessions
|
const pollSessions = (testCoerce<{ pollSessions: () => Promise<void> }>(manager)).pollSessions
|
||||||
await pollSessions.call(manager)
|
await pollSessions.call(manager)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
@@ -171,7 +171,7 @@ describe("TmuxPollingManager overlap", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const manager = new TmuxPollingManager(
|
const manager = new TmuxPollingManager(
|
||||||
client as unknown as import("../../tools/delegate-task/types").OpencodeClient,
|
testCoerce<import("../../tools/delegate-task/types").OpencodeClient>(client),
|
||||||
sessions,
|
sessions,
|
||||||
async (sessionId) => {
|
async (sessionId) => {
|
||||||
closedSessionIds.push(sessionId)
|
closedSessionIds.push(sessionId)
|
||||||
@@ -179,7 +179,7 @@ describe("TmuxPollingManager overlap", () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const pollSessions = (manager as unknown as { pollSessions: () => Promise<void> }).pollSessions
|
const pollSessions = (testCoerce<{ pollSessions: () => Promise<void> }>(manager)).pollSessions
|
||||||
await pollSessions.call(manager)
|
await pollSessions.call(manager)
|
||||||
|
|
||||||
// then
|
// then
|
||||||
@@ -222,13 +222,13 @@ describe("TmuxPollingManager overlap", () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
manager = new TmuxPollingManager(
|
manager = new TmuxPollingManager(
|
||||||
client as unknown as import("../../tools/delegate-task/types").OpencodeClient,
|
testCoerce<import("../../tools/delegate-task/types").OpencodeClient>(client),
|
||||||
sessions,
|
sessions,
|
||||||
async (sessionId) => {
|
async (sessionId) => {
|
||||||
closedSessionIds.push(sessionId)
|
closedSessionIds.push(sessionId)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
const pollSessions = (manager as unknown as { pollSessions: () => Promise<void> }).pollSessions
|
const pollSessions = (testCoerce<{ pollSessions: () => Promise<void> }>(manager)).pollSessions
|
||||||
|
|
||||||
// when
|
// when
|
||||||
await pollSessions.call(manager)
|
await pollSessions.call(manager)
|
||||||
|
|||||||
Reference in New Issue
Block a user