refactor(sdk): narrow response fallbacks
Replace unsafe unknown-array assertions with generic fallback types and explicit todo status narrowing. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -2,7 +2,7 @@ import pc from "picocolors"
|
||||
import type { RunContext } from "./types"
|
||||
import type { EventState } from "./events"
|
||||
import { checkCompletionConditions } from "./completion"
|
||||
import { normalizeSDKResponse } from "../../shared"
|
||||
import { isRecord, normalizeSDKResponse } from "../../shared"
|
||||
|
||||
const DEFAULT_POLL_INTERVAL_MS = 500
|
||||
const DEFAULT_REQUIRED_CONSECUTIVE = 1
|
||||
@@ -11,6 +11,17 @@ const MIN_STABILIZATION_MS = 1_000
|
||||
const DEFAULT_EVENT_WATCHDOG_MS = 30_000 // 30 seconds
|
||||
const DEFAULT_SECONDARY_MEANINGFUL_WORK_TIMEOUT_MS = 60_000 // 60 seconds
|
||||
|
||||
type SessionStatusMap = Record<string, { type?: string }>
|
||||
|
||||
function isIncompleteTodo(value: unknown): boolean {
|
||||
if (!isRecord(value)) {
|
||||
return true
|
||||
}
|
||||
|
||||
const status = value.status
|
||||
return status !== "completed" && status !== "cancelled"
|
||||
}
|
||||
|
||||
export interface PollOptions {
|
||||
pollIntervalMs?: number
|
||||
requiredConsecutive?: number
|
||||
@@ -123,22 +134,18 @@ export async function pollForCompletion(
|
||||
path: { id: ctx.sessionID },
|
||||
query: { directory: ctx.directory },
|
||||
})
|
||||
const children = normalizeSDKResponse(childrenRes, [] as unknown[])
|
||||
const children = normalizeSDKResponse<unknown[]>(childrenRes, [])
|
||||
const todosRes = await ctx.client.session.todo({
|
||||
path: { id: ctx.sessionID },
|
||||
query: { directory: ctx.directory },
|
||||
})
|
||||
const todos = normalizeSDKResponse(todosRes, [] as unknown[])
|
||||
const todos = normalizeSDKResponse<unknown[]>(todosRes, [])
|
||||
|
||||
const hasActiveChildren =
|
||||
Array.isArray(children) && children.length > 0
|
||||
const hasActiveTodos =
|
||||
Array.isArray(todos) &&
|
||||
todos.some(
|
||||
(t: unknown) =>
|
||||
(t as { status?: string })?.status !== "completed" &&
|
||||
(t as { status?: string })?.status !== "cancelled"
|
||||
)
|
||||
todos.some(isIncompleteTodo)
|
||||
const hasActiveWork = hasActiveChildren || hasActiveTodos
|
||||
|
||||
if (hasActiveWork) {
|
||||
@@ -189,10 +196,7 @@ async function getMainSessionStatus(
|
||||
const statusesRes = await ctx.client.session.status({
|
||||
query: { directory: ctx.directory },
|
||||
})
|
||||
const statuses = normalizeSDKResponse(
|
||||
statusesRes,
|
||||
{} as Record<string, { type?: string }>
|
||||
)
|
||||
const statuses = normalizeSDKResponse<SessionStatusMap>(statusesRes, {})
|
||||
if (!(ctx.sessionID in statuses)) {
|
||||
return "idle"
|
||||
}
|
||||
|
||||
@@ -189,8 +189,8 @@ export function createReadImageResizerHook(_ctx: PluginInput) {
|
||||
}
|
||||
}
|
||||
|
||||
if (attachmentsToRemove.length > 0) {
|
||||
const rawAttachments = outputRecord.attachments as unknown[]
|
||||
if (attachmentsToRemove.length > 0 && Array.isArray(outputRecord.attachments)) {
|
||||
const rawAttachments = outputRecord.attachments
|
||||
for (const toRemove of attachmentsToRemove) {
|
||||
const removeIndex = rawAttachments.indexOf(toRemove)
|
||||
if (removeIndex !== -1) {
|
||||
|
||||
@@ -62,7 +62,7 @@ export async function readMessagesFromSDK(
|
||||
): Promise<StoredMessageMeta[]> {
|
||||
try {
|
||||
const response = await client.session.messages({ path: { id: sessionID } })
|
||||
const data = normalizeSDKResponse(response, [] as unknown[], {
|
||||
const data = normalizeSDKResponse<unknown[]>(response, [], {
|
||||
preferResponseOnMissingData: true,
|
||||
})
|
||||
if (!Array.isArray(data)) return []
|
||||
|
||||
Reference in New Issue
Block a user