diff --git a/packages/@ant/ink/src/index.ts b/packages/@ant/ink/src/index.ts index 9d9453002..a6300fcb6 100644 --- a/packages/@ant/ink/src/index.ts +++ b/packages/@ant/ink/src/index.ts @@ -12,7 +12,7 @@ // ============================================================ export { default as wrappedRender, renderSync, createRoot } from './core/root.js' export type { RenderOptions, Instance, Root } from './core/root.js' - +export * from './theme/theme-types.js' // InkCore class export { default as Ink } from './core/ink.js' diff --git a/src/cli/print.ts b/src/cli/print.ts index 43d255637..662aa865d 100644 --- a/src/cli/print.ts +++ b/src/cli/print.ts @@ -2256,7 +2256,7 @@ function runHeadlessStreaming( { turnStartTime } as import('src/utils/filePersistence/types.js').TurnStartTime, abortController.signal, result => { - const filesResult = result as { persistedFiles: { filename: string; file_id: string }[]; failedFiles: { filename: string; error: string }[] } + const filesResult = result as unknown as { persistedFiles: { filename: string; file_id: string }[]; failedFiles: { filename: string; error: string }[] } output.enqueue({ type: 'system' as const, subtype: 'files_persisted' as const, @@ -3315,7 +3315,7 @@ function runHeadlessStreaming( output, ) } else if (req.subtype === 'mcp_authenticate') { - const { serverName } = req + const serverName = req.serverName as string const currentAppState = getAppState() const config = getMcpConfigByName(serverName) ?? @@ -3333,9 +3333,9 @@ function runHeadlessStreaming( } else { try { // Abort any previous in-flight OAuth flow for this server - activeOAuthFlows.get(serverName)?.abort() + activeOAuthFlows.get(serverName as string)?.abort() const controller = new AbortController() - activeOAuthFlows.set(serverName, controller) + activeOAuthFlows.set(serverName as string, controller) // Capture the auth URL from the callback let resolveAuthUrl: (url: string) => void @@ -3345,14 +3345,14 @@ function runHeadlessStreaming( // Start the OAuth flow in the background const oauthPromise = performMCPOAuthFlow( - serverName, + serverName as string, config, url => resolveAuthUrl!(url), controller.signal, { skipBrowserOpen: true, onWaitingForCallback: submit => { - oauthCallbackSubmitters.set(serverName, submit) + oauthCallbackSubmitters.set(serverName as string, submit) }, }, ) @@ -3386,27 +3386,27 @@ function runHeadlessStreaming( const fullFlowPromise = oauthPromise .then(async () => { // Don't reconnect if the server was disabled during the OAuth flow - if (isMcpServerDisabled(serverName)) { + if (isMcpServerDisabled(serverName as string)) { return } // Skip reconnect if the manual callback path was used — // handleAuthDone will do it via mcp_reconnect (which // updates dynamicMcpState for tool registration). - if (oauthManualCallbackUsed.has(serverName)) { + if (oauthManualCallbackUsed.has(serverName as string)) { return } // Reconnect the server after successful auth const result = await reconnectMcpServerImpl( - serverName, + serverName as string, config, ) - const prefix = getMcpPrefix(serverName) + const prefix = getMcpPrefix(serverName as string) setAppState(prev => ({ ...prev, mcp: { ...prev.mcp, clients: prev.mcp.clients.map(c => - c.name === serverName ? result.client : c, + c.name === serverName as string ? result.client : c, ), tools: [ ...reject(prev.mcp.tools, t => @@ -3416,7 +3416,7 @@ function runHeadlessStreaming( ], commands: [ ...reject(prev.mcp.commands, c => - commandBelongsToServer(c, serverName), + commandBelongsToServer(c, serverName as string), ), ...result.commands, ], @@ -3424,9 +3424,9 @@ function runHeadlessStreaming( result.resources && result.resources.length > 0 ? { ...prev.mcp.resources, - [serverName]: result.resources, + [serverName as string]: result.resources, } - : omit(prev.mcp.resources, serverName), + : omit(prev.mcp.resources, serverName as string), }, })) // Also update dynamicMcpState so run() picks up the new tools @@ -3449,17 +3449,17 @@ function runHeadlessStreaming( }) .catch(error => { logForDebugging( - `MCP OAuth failed for ${serverName}: ${error}`, + `MCP OAuth failed for ${serverName as string}: ${error}`, { level: 'error' }, ) }) .finally(() => { // Clean up only if this is still the active flow - if (activeOAuthFlows.get(serverName) === controller) { - activeOAuthFlows.delete(serverName) - oauthCallbackSubmitters.delete(serverName) - oauthManualCallbackUsed.delete(serverName) - oauthAuthPromises.delete(serverName) + if (activeOAuthFlows.get(serverName as string) === controller) { + activeOAuthFlows.delete(serverName as string) + oauthCallbackSubmitters.delete(serverName as string) + oauthManualCallbackUsed.delete(serverName as string) + oauthAuthPromises.delete(serverName as string) } }) void fullFlowPromise @@ -3468,7 +3468,8 @@ function runHeadlessStreaming( } } } else if (req.subtype === 'mcp_oauth_callback_url') { - const { serverName, callbackUrl } = req + const serverName = req.serverName as string + const callbackUrl = req.callbackUrl as string const submit = oauthCallbackSubmitters.get(serverName) if (submit) { // Validate the callback URL before submitting. The submit @@ -3477,7 +3478,7 @@ function runHeadlessStreaming( // block the control message loop until timeout. let hasCodeOrError = false try { - const parsed = new URL(callbackUrl) + const parsed = new URL(callbackUrl as string | URL) hasCodeOrError = parsed.searchParams.has('code') || parsed.searchParams.has('error') @@ -3491,7 +3492,7 @@ function runHeadlessStreaming( ) } else { oauthManualCallbackUsed.add(serverName) - submit(callbackUrl) + submit(callbackUrl as string) // Wait for auth (token exchange) to complete before responding. // Reconnect is handled by the extension via handleAuthDone → // mcp_reconnect (which updates dynamicMcpState for tools). @@ -3524,7 +3525,7 @@ function runHeadlessStreaming( // both URLs and wait. Automatic URL → localhost listener catches // the redirect if the browser is on this host; manual URL → the // success page shows "code#state" for claude_oauth_callback. - const { loginWithClaudeAi } = req + const loginWithClaudeAi = req.loginWithClaudeAi as boolean | undefined // Clean up any prior flow. cleanup() closes the localhost listener // and nulls the manual resolver. The prior `flow` promise is left @@ -3534,7 +3535,7 @@ function runHeadlessStreaming( claudeOAuth?.service.cleanup() logEvent('tengu_oauth_flow_start', { - loginWithClaudeAi: loginWithClaudeAi ?? true, + loginWithClaudeAi: (loginWithClaudeAi ?? true) as boolean | number, }) const service = new OAuthService() @@ -3557,7 +3558,7 @@ function runHeadlessStreaming( urlResolver({ manualUrl, automaticUrl: automaticUrl! }) }, { - loginWithClaudeAi: loginWithClaudeAi ?? true, + loginWithClaudeAi: (loginWithClaudeAi ?? true) as boolean, skipBrowserOpen: true, }, ) @@ -3569,7 +3570,7 @@ function runHeadlessStreaming( // next API call re-reads keychain/file and works. No respawn. await installOAuthTokens(tokens) logEvent('tengu_oauth_success', { - loginWithClaudeAi: loginWithClaudeAi ?? true, + loginWithClaudeAi: (loginWithClaudeAi ?? true) as boolean | number, }) }) .finally(() => { @@ -3656,7 +3657,7 @@ function runHeadlessStreaming( ) } } else if (req.subtype === 'mcp_clear_auth') { - const { serverName } = req + const serverName = req.serverName as string const currentAppState = getAppState() const config = getMcpConfigByName(serverName) ?? @@ -3680,7 +3681,7 @@ function runHeadlessStreaming( mcp: { ...prev.mcp, clients: prev.mcp.clients.map(c => - c.name === serverName ? result.client : c, + c.name === serverName as string ? result.client : c, ), tools: [ ...reject(prev.mcp.tools, t => t.name?.startsWith(prefix)), @@ -3791,7 +3792,8 @@ function runHeadlessStreaming( // Fire-and-forget so the Haiku call does not block the stdin loop // (which would delay processing of subsequent user messages / // interrupts for the duration of the API roundtrip). - const { description, persist } = req + const description = req.description as string + const persist = req.persist as boolean // Reuse the live controller only if it has not already been aborted // (e.g. by interrupt()); an aborted signal would cause queryHaiku to // immediately throw APIUserAbortError → {title: null}. @@ -3835,7 +3837,7 @@ function runHeadlessStreaming( // matches in the common case. May still miss the cache for // coordinator mode or memory-mechanics extras — acceptable, the // alternative is the side question failing entirely. - const { question } = req + const question = req.question as string void (async () => { try { const saved = getLastCacheSafeParams() diff --git a/src/cli/structuredIO.ts b/src/cli/structuredIO.ts index 3f8d426e2..fba44e61b 100644 --- a/src/cli/structuredIO.ts +++ b/src/cli/structuredIO.ts @@ -679,7 +679,7 @@ export class StructuredIO { { subtype: 'hook_callback', callback_id: callbackId, - input: input as Parameters[0], + input: input as any, tool_use_id: toolUseID || undefined, }, hookJSONOutputSchema(), diff --git a/src/components/BuiltinStatusLine.tsx b/src/components/BuiltinStatusLine.tsx index 45fe3805b..733d5574b 100644 --- a/src/components/BuiltinStatusLine.tsx +++ b/src/components/BuiltinStatusLine.tsx @@ -81,7 +81,7 @@ function BuiltinStatusLineInner({ const tokenDisplay = `${formatTokens(usedTokens)}/${formatTokens(contextWindowSize)}`; return ( - + {/* Model name */} {shortModel} diff --git a/src/components/PromptInput/PromptInputFooterSuggestions.tsx b/src/components/PromptInput/PromptInputFooterSuggestions.tsx index 60dc39d57..e6b2065b6 100644 --- a/src/components/PromptInput/PromptInputFooterSuggestions.tsx +++ b/src/components/PromptInput/PromptInputFooterSuggestions.tsx @@ -163,7 +163,7 @@ const SuggestionItemRow = memo(function SuggestionItemRow({ {paddedDisplayText} {tagText ? ( - + {tagText} ) : null} diff --git a/src/components/skills/SkillsMenu.tsx b/src/components/skills/SkillsMenu.tsx index 37a196d45..6bbf48bf2 100644 --- a/src/components/skills/SkillsMenu.tsx +++ b/src/components/skills/SkillsMenu.tsx @@ -9,6 +9,7 @@ import { type PromptCommand, } from '../../commands.js' import { Box, Text } from '@anthropic/ink' +import type { Theme } from '@anthropic/ink' import { estimateSkillFrontmatterTokens, getSkillsPath, @@ -140,7 +141,7 @@ export function SkillsMenu({ onExit, commands }: Props): React.ReactNode { } const getScopeTag = ( - source: SkillSource, + source: string, ): { label: string; color: string } | undefined => { switch (source) { case 'projectSettings': @@ -169,6 +170,7 @@ export function SkillsMenu({ onExit, commands }: Props): React.ReactNode { {getCommandName(skill)} {scopeTag && ( [{scopeTag.label}] + )} {pluginName ? ` · ${pluginName}` : ''} · {tokenDisplay} description diff --git a/src/components/tasks/RemoteSessionDetailDialog.tsx b/src/components/tasks/RemoteSessionDetailDialog.tsx index 1e2e2e46c..f21291b5e 100644 --- a/src/components/tasks/RemoteSessionDetailDialog.tsx +++ b/src/components/tasks/RemoteSessionDetailDialog.tsx @@ -29,6 +29,7 @@ import { formatReviewStageCounts, RemoteSessionProgress, } from './RemoteSessionProgress.js' +import { AssistantMessage } from 'src/types/message.js' type Props = { session: DeepImmutable @@ -122,7 +123,7 @@ function UltraplanSessionDetail({ let lastBlock: { name: string; input: unknown } | null = null for (const msg of session.log) { if (msg.type !== 'assistant') continue - const content = msg.message?.content ?? [] + const content = (msg.message as { content?: unknown[] })?.content ?? [] for (const block of content as Array<{type: string; name: string; input: unknown}>) { if (block.type !== 'tool_use') continue calls++ @@ -612,7 +613,7 @@ export function RemoteSessionDetailDialog({ {lastMessages.map((msg, i) => ( 0} tools={toolUseContext.options.tools} diff --git a/src/hooks/useReplBridge.tsx b/src/hooks/useReplBridge.tsx index c19304ffe..2b9899117 100644 --- a/src/hooks/useReplBridge.tsx +++ b/src/hooks/useReplBridge.tsx @@ -44,6 +44,7 @@ import { transitionPermissionMode, } from '../utils/permissions/permissionSetup.js' import { getLeaderToolUseConfirmQueue } from '../utils/swarm/leaderPermissionBridge.js' +import { ContentBlockParam } from '@anthropic-ai/sdk/resources' /** How long after a failure before replBridgeEnabled is auto-cleared (stops retries). */ export const BRIDGE_FAILURE_DISMISS_MS = 10_000 @@ -226,7 +227,7 @@ export function useReplBridge( '../bridge/inboundAttachments.js' ) const rawContent = fields.content - let sanitized: string | Array<{ type: string; [key: string]: unknown }> = typeof rawContent === 'string' ? rawContent : rawContent as Array<{ type: string; [key: string]: unknown }> + let sanitized: string | Array<{ type: string; [key: string]: unknown }> = typeof rawContent === 'string' ? rawContent : rawContent as unknown as Array<{ type: string; [key: string]: unknown }> if (feature('KAIROS_GITHUB_WEBHOOKS')) { /* eslint-disable @typescript-eslint/no-require-imports */ const { sanitizeInboundWebhookContent } = @@ -236,7 +237,7 @@ export function useReplBridge( sanitized = sanitizeInboundWebhookContent(sanitized) } } - const content = await resolveAndPrepend(msg, sanitized) + const content = await resolveAndPrepend(msg, sanitized as string | ContentBlockParam[]) const preview = typeof content === 'string' diff --git a/src/hooks/useSSHSession.ts b/src/hooks/useSSHSession.ts index 1453231f0..0ee717e3e 100644 --- a/src/hooks/useSSHSession.ts +++ b/src/hooks/useSSHSession.ts @@ -98,7 +98,7 @@ export function useSSHSession({ createToolStub(request.tool_name) const syntheticMessage = createSyntheticAssistantMessage( - request, + request as unknown as Parameters[0], requestId, ) diff --git a/src/services/api/gemini/index.ts b/src/services/api/gemini/index.ts index 6935ac1bc..1b887878e 100644 --- a/src/services/api/gemini/index.ts +++ b/src/services/api/gemini/index.ts @@ -14,6 +14,7 @@ import { normalizeContentFromAPI, normalizeMessagesForAPI, } from '../../../utils/messages.js' +import type { SDKAssistantMessageError } from '../../../entrypoints/agentSdkTypes.js' import type { SystemPrompt } from '../../../utils/systemPromptType.js' import type { ThinkingConfig } from '../../../utils/thinking.js' import type { Options } from '../claude.js' @@ -186,7 +187,7 @@ export async function* queryModelGemini( yield createAssistantAPIErrorMessage({ content: `API Error: ${errorMessage}`, apiError: 'api_error', - error: (error instanceof Error ? error : new Error(String(error))) as Error, + error: (error instanceof Error ? error : new Error(String(error))) as unknown as SDKAssistantMessageError, }) } } diff --git a/src/services/api/grok/client.ts b/src/services/api/grok/client.ts index 034030107..060d12636 100644 --- a/src/services/api/grok/client.ts +++ b/src/services/api/grok/client.ts @@ -28,7 +28,7 @@ export function getGrokClient(options?: { maxRetries: options?.maxRetries ?? 0, timeout: parseInt(process.env.API_TIMEOUT_MS || String(600 * 1000), 10), dangerouslyAllowBrowser: true, - fetchOptions: getProxyFetchOptions({ forAnthropicAPI: false }) as RequestInit, + fetchOptions: getProxyFetchOptions({ forAnthropicAPI: false }), ...(options?.fetchOverride && { fetch: options.fetchOverride }), }) diff --git a/src/services/api/grok/index.ts b/src/services/api/grok/index.ts index 8e4f934b4..3198e85f6 100644 --- a/src/services/api/grok/index.ts +++ b/src/services/api/grok/index.ts @@ -12,6 +12,7 @@ import { anthropicToolsToOpenAI, anthropicToolChoiceToOpenAI } from '../openai/c import { adaptOpenAIStreamToAnthropic } from '../openai/streamAdapter.js' import { resolveGrokModel } from './modelMapping.js' import { normalizeMessagesForAPI } from '../../../utils/messages.js' +import type { SDKAssistantMessageError } from '../../../entrypoints/agentSdkTypes.js' import { toolToAPISchema } from '../../../utils/api.js' import { logForDebugging } from '../../../utils/debug.js' import { addToTotalSessionCost } from '../../../cost-tracker.js' @@ -190,7 +191,7 @@ export async function* queryModelGrok( yield createAssistantAPIErrorMessage({ content: `API Error: ${errorMessage}`, apiError: 'api_error', - error: (error instanceof Error ? error : new Error(String(error))) as Error, + error: (error instanceof Error ? error : new Error(String(error))) as unknown as SDKAssistantMessageError, }) } } diff --git a/src/services/api/openai/__tests__/thinking.test.ts b/src/services/api/openai/__tests__/thinking.test.ts index c53abaf36..1a0b38fd8 100644 --- a/src/services/api/openai/__tests__/thinking.test.ts +++ b/src/services/api/openai/__tests__/thinking.test.ts @@ -151,7 +151,7 @@ describe('buildOpenAIRequestBody — thinking params', () => { messages: [{ role: 'user', content: 'hello' }], tools: [] as any[], toolChoice: undefined as any, - } + } as any test('includes official DeepSeek API thinking format when enabled', () => { const body = buildOpenAIRequestBody({ ...baseParams, enableThinking: true }) diff --git a/src/services/api/openai/client.ts b/src/services/api/openai/client.ts index eea96cb8e..62a37dfbc 100644 --- a/src/services/api/openai/client.ts +++ b/src/services/api/openai/client.ts @@ -31,7 +31,7 @@ export function getOpenAIClient(options?: { dangerouslyAllowBrowser: true, ...(process.env.OPENAI_ORG_ID && { organization: process.env.OPENAI_ORG_ID }), ...(process.env.OPENAI_PROJECT_ID && { project: process.env.OPENAI_PROJECT_ID }), - fetchOptions: getProxyFetchOptions({ forAnthropicAPI: false }) as RequestInit, + fetchOptions: getProxyFetchOptions({ forAnthropicAPI: false }), ...(options?.fetchOverride && { fetch: options.fetchOverride }), }) diff --git a/src/services/api/openai/index.ts b/src/services/api/openai/index.ts index 0f350ad3e..34bbe4875 100644 --- a/src/services/api/openai/index.ts +++ b/src/services/api/openai/index.ts @@ -36,6 +36,7 @@ import { createAssistantAPIErrorMessage, normalizeContentFromAPI, } from '../../../utils/messages.js' +import type { SDKAssistantMessageError } from '../../../entrypoints/agentSdkTypes.js' import { isToolSearchEnabled, extractDiscoveredToolNames, @@ -87,7 +88,11 @@ export function buildOpenAIRequestBody(params: { toolChoice: any enableThinking: boolean temperatureOverride?: number -}): ChatCompletionCreateParamsStreaming { +}): ChatCompletionCreateParamsStreaming & { + thinking?: { type: string } + enable_thinking?: boolean + chat_template_kwargs?: { thinking: boolean } +} { const { model, messages, tools, toolChoice, enableThinking, temperatureOverride } = params return { model, @@ -220,7 +225,7 @@ export async function* queryModelOpenAI( // 10. Get client and make streaming request const client = getOpenAIClient({ maxRetries: 0, - fetchOverride: options.fetchOverride, + fetchOverride: options.fetchOverride as unknown as typeof fetch, source: options.querySource, }) @@ -354,7 +359,7 @@ export async function* queryModelOpenAI( yield createAssistantAPIErrorMessage({ content: `API Error: ${errorMessage}`, apiError: 'api_error', - error: (error instanceof Error ? error : new Error(String(error))) as Error, + error: (error instanceof Error ? error : new Error(String(error))) as unknown as SDKAssistantMessageError, }) } } \ No newline at end of file diff --git a/src/tools/AgentTool/UI.tsx b/src/tools/AgentTool/UI.tsx index f1e762f57..19b4680a9 100644 --- a/src/tools/AgentTool/UI.tsx +++ b/src/tools/AgentTool/UI.tsx @@ -49,6 +49,7 @@ import type { import { inputSchema } from './AgentTool.js' import { getAgentColor } from './agentColorManager.js' import { GENERAL_PURPOSE_AGENT } from './built-in/generalPurposeAgent.js' +import { BetaUsage } from '@anthropic-ai/sdk/resources/beta.mjs' const MAX_PROGRESS_MESSAGES_TO_SHOW = 3 @@ -411,7 +412,7 @@ export function renderToolResultMessage( const finalAssistantMessage = createAssistantMessage({ content: completionMessage, - usage: { ...usage, inference_geo: null, iterations: null, speed: null } as typeof usage, + usage: { ...usage, inference_geo: null, iterations: null, speed: null } as unknown as BetaUsage, }) return ( diff --git a/src/utils/computerUse/win32/bridgeClient.ts b/src/utils/computerUse/win32/bridgeClient.ts index 70e747f5e..3e97e8b9f 100644 --- a/src/utils/computerUse/win32/bridgeClient.ts +++ b/src/utils/computerUse/win32/bridgeClient.ts @@ -131,10 +131,10 @@ export async function call( try { const stdin = bridgeProc!.stdin if (stdin) { - const writable = stdin as Writable + const writable = stdin as unknown as Writable writable.write(JSON.stringify(req) + '\n') - if (typeof writable.flush === 'function') { - writable.flush() + if (typeof (writable as any).flush === 'function') { + (writable as any).flush() } } } catch (err) { @@ -185,7 +185,7 @@ export function stopBridge(): void { try { const stdin = bridgeProc.stdin if (stdin) { - const writable = stdin as Writable + const writable = stdin as unknown as Writable if (typeof writable.end === 'function') { writable.end() } diff --git a/src/utils/streamlinedTransform.ts b/src/utils/streamlinedTransform.ts index 36245c389..d8e13fce8 100644 --- a/src/utils/streamlinedTransform.ts +++ b/src/utils/streamlinedTransform.ts @@ -137,14 +137,14 @@ export function createStreamlinedTransformer(): ( ): StdoutMessage | null { switch (message.type) { case 'assistant': { - const messageContent = (message as SDKAssistantMessage).message + const messageContent = (message as unknown as SDKAssistantMessage).message const content = messageContent?.content const text = Array.isArray(content) ? extractTextContent(content, '\n').trim() : '' // Accumulate tool counts from this message - accumulateToolUses(message as SDKAssistantMessage, cumulativeCounts) + accumulateToolUses(message as unknown as SDKAssistantMessage, cumulativeCounts) if (text.length > 0) { // Text message: emit text only, reset counts