fix: 修复类型问题

This commit is contained in:
claude-code-best
2026-04-10 17:34:01 +08:00
parent e70319e8f5
commit ff03fe7fcb
18 changed files with 70 additions and 56 deletions

View File

@@ -12,7 +12,7 @@
// ============================================================ // ============================================================
export { default as wrappedRender, renderSync, createRoot } from './core/root.js' export { default as wrappedRender, renderSync, createRoot } from './core/root.js'
export type { RenderOptions, Instance, Root } from './core/root.js' export type { RenderOptions, Instance, Root } from './core/root.js'
export * from './theme/theme-types.js'
// InkCore class // InkCore class
export { default as Ink } from './core/ink.js' export { default as Ink } from './core/ink.js'

View File

@@ -2256,7 +2256,7 @@ function runHeadlessStreaming(
{ turnStartTime } as import('src/utils/filePersistence/types.js').TurnStartTime, { turnStartTime } as import('src/utils/filePersistence/types.js').TurnStartTime,
abortController.signal, abortController.signal,
result => { 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({ output.enqueue({
type: 'system' as const, type: 'system' as const,
subtype: 'files_persisted' as const, subtype: 'files_persisted' as const,
@@ -3315,7 +3315,7 @@ function runHeadlessStreaming(
output, output,
) )
} else if (req.subtype === 'mcp_authenticate') { } else if (req.subtype === 'mcp_authenticate') {
const { serverName } = req const serverName = req.serverName as string
const currentAppState = getAppState() const currentAppState = getAppState()
const config = const config =
getMcpConfigByName(serverName) ?? getMcpConfigByName(serverName) ??
@@ -3333,9 +3333,9 @@ function runHeadlessStreaming(
} else { } else {
try { try {
// Abort any previous in-flight OAuth flow for this server // Abort any previous in-flight OAuth flow for this server
activeOAuthFlows.get(serverName)?.abort() activeOAuthFlows.get(serverName as string)?.abort()
const controller = new AbortController() const controller = new AbortController()
activeOAuthFlows.set(serverName, controller) activeOAuthFlows.set(serverName as string, controller)
// Capture the auth URL from the callback // Capture the auth URL from the callback
let resolveAuthUrl: (url: string) => void let resolveAuthUrl: (url: string) => void
@@ -3345,14 +3345,14 @@ function runHeadlessStreaming(
// Start the OAuth flow in the background // Start the OAuth flow in the background
const oauthPromise = performMCPOAuthFlow( const oauthPromise = performMCPOAuthFlow(
serverName, serverName as string,
config, config,
url => resolveAuthUrl!(url), url => resolveAuthUrl!(url),
controller.signal, controller.signal,
{ {
skipBrowserOpen: true, skipBrowserOpen: true,
onWaitingForCallback: submit => { onWaitingForCallback: submit => {
oauthCallbackSubmitters.set(serverName, submit) oauthCallbackSubmitters.set(serverName as string, submit)
}, },
}, },
) )
@@ -3386,27 +3386,27 @@ function runHeadlessStreaming(
const fullFlowPromise = oauthPromise const fullFlowPromise = oauthPromise
.then(async () => { .then(async () => {
// Don't reconnect if the server was disabled during the OAuth flow // Don't reconnect if the server was disabled during the OAuth flow
if (isMcpServerDisabled(serverName)) { if (isMcpServerDisabled(serverName as string)) {
return return
} }
// Skip reconnect if the manual callback path was used — // Skip reconnect if the manual callback path was used —
// handleAuthDone will do it via mcp_reconnect (which // handleAuthDone will do it via mcp_reconnect (which
// updates dynamicMcpState for tool registration). // updates dynamicMcpState for tool registration).
if (oauthManualCallbackUsed.has(serverName)) { if (oauthManualCallbackUsed.has(serverName as string)) {
return return
} }
// Reconnect the server after successful auth // Reconnect the server after successful auth
const result = await reconnectMcpServerImpl( const result = await reconnectMcpServerImpl(
serverName, serverName as string,
config, config,
) )
const prefix = getMcpPrefix(serverName) const prefix = getMcpPrefix(serverName as string)
setAppState(prev => ({ setAppState(prev => ({
...prev, ...prev,
mcp: { mcp: {
...prev.mcp, ...prev.mcp,
clients: prev.mcp.clients.map(c => clients: prev.mcp.clients.map(c =>
c.name === serverName ? result.client : c, c.name === serverName as string ? result.client : c,
), ),
tools: [ tools: [
...reject(prev.mcp.tools, t => ...reject(prev.mcp.tools, t =>
@@ -3416,7 +3416,7 @@ function runHeadlessStreaming(
], ],
commands: [ commands: [
...reject(prev.mcp.commands, c => ...reject(prev.mcp.commands, c =>
commandBelongsToServer(c, serverName), commandBelongsToServer(c, serverName as string),
), ),
...result.commands, ...result.commands,
], ],
@@ -3424,9 +3424,9 @@ function runHeadlessStreaming(
result.resources && result.resources.length > 0 result.resources && result.resources.length > 0
? { ? {
...prev.mcp.resources, ...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 // Also update dynamicMcpState so run() picks up the new tools
@@ -3449,17 +3449,17 @@ function runHeadlessStreaming(
}) })
.catch(error => { .catch(error => {
logForDebugging( logForDebugging(
`MCP OAuth failed for ${serverName}: ${error}`, `MCP OAuth failed for ${serverName as string}: ${error}`,
{ level: 'error' }, { level: 'error' },
) )
}) })
.finally(() => { .finally(() => {
// Clean up only if this is still the active flow // Clean up only if this is still the active flow
if (activeOAuthFlows.get(serverName) === controller) { if (activeOAuthFlows.get(serverName as string) === controller) {
activeOAuthFlows.delete(serverName) activeOAuthFlows.delete(serverName as string)
oauthCallbackSubmitters.delete(serverName) oauthCallbackSubmitters.delete(serverName as string)
oauthManualCallbackUsed.delete(serverName) oauthManualCallbackUsed.delete(serverName as string)
oauthAuthPromises.delete(serverName) oauthAuthPromises.delete(serverName as string)
} }
}) })
void fullFlowPromise void fullFlowPromise
@@ -3468,7 +3468,8 @@ function runHeadlessStreaming(
} }
} }
} else if (req.subtype === 'mcp_oauth_callback_url') { } 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) const submit = oauthCallbackSubmitters.get(serverName)
if (submit) { if (submit) {
// Validate the callback URL before submitting. The submit // Validate the callback URL before submitting. The submit
@@ -3477,7 +3478,7 @@ function runHeadlessStreaming(
// block the control message loop until timeout. // block the control message loop until timeout.
let hasCodeOrError = false let hasCodeOrError = false
try { try {
const parsed = new URL(callbackUrl) const parsed = new URL(callbackUrl as string | URL)
hasCodeOrError = hasCodeOrError =
parsed.searchParams.has('code') || parsed.searchParams.has('code') ||
parsed.searchParams.has('error') parsed.searchParams.has('error')
@@ -3491,7 +3492,7 @@ function runHeadlessStreaming(
) )
} else { } else {
oauthManualCallbackUsed.add(serverName) oauthManualCallbackUsed.add(serverName)
submit(callbackUrl) submit(callbackUrl as string)
// Wait for auth (token exchange) to complete before responding. // Wait for auth (token exchange) to complete before responding.
// Reconnect is handled by the extension via handleAuthDone → // Reconnect is handled by the extension via handleAuthDone →
// mcp_reconnect (which updates dynamicMcpState for tools). // mcp_reconnect (which updates dynamicMcpState for tools).
@@ -3524,7 +3525,7 @@ function runHeadlessStreaming(
// both URLs and wait. Automatic URL → localhost listener catches // both URLs and wait. Automatic URL → localhost listener catches
// the redirect if the browser is on this host; manual URL → the // the redirect if the browser is on this host; manual URL → the
// success page shows "code#state" for claude_oauth_callback. // 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 // Clean up any prior flow. cleanup() closes the localhost listener
// and nulls the manual resolver. The prior `flow` promise is left // and nulls the manual resolver. The prior `flow` promise is left
@@ -3534,7 +3535,7 @@ function runHeadlessStreaming(
claudeOAuth?.service.cleanup() claudeOAuth?.service.cleanup()
logEvent('tengu_oauth_flow_start', { logEvent('tengu_oauth_flow_start', {
loginWithClaudeAi: loginWithClaudeAi ?? true, loginWithClaudeAi: (loginWithClaudeAi ?? true) as boolean | number,
}) })
const service = new OAuthService() const service = new OAuthService()
@@ -3557,7 +3558,7 @@ function runHeadlessStreaming(
urlResolver({ manualUrl, automaticUrl: automaticUrl! }) urlResolver({ manualUrl, automaticUrl: automaticUrl! })
}, },
{ {
loginWithClaudeAi: loginWithClaudeAi ?? true, loginWithClaudeAi: (loginWithClaudeAi ?? true) as boolean,
skipBrowserOpen: true, skipBrowserOpen: true,
}, },
) )
@@ -3569,7 +3570,7 @@ function runHeadlessStreaming(
// next API call re-reads keychain/file and works. No respawn. // next API call re-reads keychain/file and works. No respawn.
await installOAuthTokens(tokens) await installOAuthTokens(tokens)
logEvent('tengu_oauth_success', { logEvent('tengu_oauth_success', {
loginWithClaudeAi: loginWithClaudeAi ?? true, loginWithClaudeAi: (loginWithClaudeAi ?? true) as boolean | number,
}) })
}) })
.finally(() => { .finally(() => {
@@ -3656,7 +3657,7 @@ function runHeadlessStreaming(
) )
} }
} else if (req.subtype === 'mcp_clear_auth') { } else if (req.subtype === 'mcp_clear_auth') {
const { serverName } = req const serverName = req.serverName as string
const currentAppState = getAppState() const currentAppState = getAppState()
const config = const config =
getMcpConfigByName(serverName) ?? getMcpConfigByName(serverName) ??
@@ -3680,7 +3681,7 @@ function runHeadlessStreaming(
mcp: { mcp: {
...prev.mcp, ...prev.mcp,
clients: prev.mcp.clients.map(c => clients: prev.mcp.clients.map(c =>
c.name === serverName ? result.client : c, c.name === serverName as string ? result.client : c,
), ),
tools: [ tools: [
...reject(prev.mcp.tools, t => t.name?.startsWith(prefix)), ...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 // Fire-and-forget so the Haiku call does not block the stdin loop
// (which would delay processing of subsequent user messages / // (which would delay processing of subsequent user messages /
// interrupts for the duration of the API roundtrip). // 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 // Reuse the live controller only if it has not already been aborted
// (e.g. by interrupt()); an aborted signal would cause queryHaiku to // (e.g. by interrupt()); an aborted signal would cause queryHaiku to
// immediately throw APIUserAbortError → {title: null}. // immediately throw APIUserAbortError → {title: null}.
@@ -3835,7 +3837,7 @@ function runHeadlessStreaming(
// matches in the common case. May still miss the cache for // matches in the common case. May still miss the cache for
// coordinator mode or memory-mechanics extras — acceptable, the // coordinator mode or memory-mechanics extras — acceptable, the
// alternative is the side question failing entirely. // alternative is the side question failing entirely.
const { question } = req const question = req.question as string
void (async () => { void (async () => {
try { try {
const saved = getLastCacheSafeParams() const saved = getLastCacheSafeParams()

View File

@@ -679,7 +679,7 @@ export class StructuredIO {
{ {
subtype: 'hook_callback', subtype: 'hook_callback',
callback_id: callbackId, callback_id: callbackId,
input: input as Parameters<HookCallback['callback']>[0], input: input as any,
tool_use_id: toolUseID || undefined, tool_use_id: toolUseID || undefined,
}, },
hookJSONOutputSchema(), hookJSONOutputSchema(),

View File

@@ -81,7 +81,7 @@ function BuiltinStatusLineInner({
const tokenDisplay = `${formatTokens(usedTokens)}/${formatTokens(contextWindowSize)}`; const tokenDisplay = `${formatTokens(usedTokens)}/${formatTokens(contextWindowSize)}`;
return ( return (
<Box wrap="truncate"> <Box>
{/* Model name */} {/* Model name */}
<Text>{shortModel}</Text> <Text>{shortModel}</Text>

View File

@@ -163,7 +163,7 @@ const SuggestionItemRow = memo(function SuggestionItemRow({
{paddedDisplayText} {paddedDisplayText}
</Text> </Text>
{tagText ? ( {tagText ? (
<Text color={item.tag === 'local' ? ('yellow' as const) : undefined} dimColor={item.tag !== 'local'}> <Text color={item.tag === 'local' ? 'ansi:yellow' : undefined} dimColor={item.tag !== 'local'}>
{tagText} {tagText}
</Text> </Text>
) : null} ) : null}

View File

@@ -9,6 +9,7 @@ import {
type PromptCommand, type PromptCommand,
} from '../../commands.js' } from '../../commands.js'
import { Box, Text } from '@anthropic/ink' import { Box, Text } from '@anthropic/ink'
import type { Theme } from '@anthropic/ink'
import { import {
estimateSkillFrontmatterTokens, estimateSkillFrontmatterTokens,
getSkillsPath, getSkillsPath,
@@ -140,7 +141,7 @@ export function SkillsMenu({ onExit, commands }: Props): React.ReactNode {
} }
const getScopeTag = ( const getScopeTag = (
source: SkillSource, source: string,
): { label: string; color: string } | undefined => { ): { label: string; color: string } | undefined => {
switch (source) { switch (source) {
case 'projectSettings': case 'projectSettings':
@@ -169,6 +170,7 @@ export function SkillsMenu({ onExit, commands }: Props): React.ReactNode {
<Text>{getCommandName(skill)}</Text> <Text>{getCommandName(skill)}</Text>
{scopeTag && ( {scopeTag && (
<Text color={scopeTag.color as keyof Theme}> [{scopeTag.label}]</Text> <Text color={scopeTag.color as keyof Theme}> [{scopeTag.label}]</Text>
)} )}
<Text dimColor> <Text dimColor>
{pluginName ? ` · ${pluginName}` : ''} · {tokenDisplay} description {pluginName ? ` · ${pluginName}` : ''} · {tokenDisplay} description

View File

@@ -29,6 +29,7 @@ import {
formatReviewStageCounts, formatReviewStageCounts,
RemoteSessionProgress, RemoteSessionProgress,
} from './RemoteSessionProgress.js' } from './RemoteSessionProgress.js'
import { AssistantMessage } from 'src/types/message.js'
type Props = { type Props = {
session: DeepImmutable<RemoteAgentTaskState> session: DeepImmutable<RemoteAgentTaskState>
@@ -122,7 +123,7 @@ function UltraplanSessionDetail({
let lastBlock: { name: string; input: unknown } | null = null let lastBlock: { name: string; input: unknown } | null = null
for (const msg of session.log) { for (const msg of session.log) {
if (msg.type !== 'assistant') continue 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}>) { for (const block of content as Array<{type: string; name: string; input: unknown}>) {
if (block.type !== 'tool_use') continue if (block.type !== 'tool_use') continue
calls++ calls++
@@ -612,7 +613,7 @@ export function RemoteSessionDetailDialog({
{lastMessages.map((msg, i) => ( {lastMessages.map((msg, i) => (
<Message <Message
key={i} key={i}
message={msg} message={msg as AssistantMessage}
lookups={EMPTY_LOOKUPS} lookups={EMPTY_LOOKUPS}
addMargin={i > 0} addMargin={i > 0}
tools={toolUseContext.options.tools} tools={toolUseContext.options.tools}

View File

@@ -44,6 +44,7 @@ import {
transitionPermissionMode, transitionPermissionMode,
} from '../utils/permissions/permissionSetup.js' } from '../utils/permissions/permissionSetup.js'
import { getLeaderToolUseConfirmQueue } from '../utils/swarm/leaderPermissionBridge.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). */ /** How long after a failure before replBridgeEnabled is auto-cleared (stops retries). */
export const BRIDGE_FAILURE_DISMISS_MS = 10_000 export const BRIDGE_FAILURE_DISMISS_MS = 10_000
@@ -226,7 +227,7 @@ export function useReplBridge(
'../bridge/inboundAttachments.js' '../bridge/inboundAttachments.js'
) )
const rawContent = fields.content 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')) { if (feature('KAIROS_GITHUB_WEBHOOKS')) {
/* eslint-disable @typescript-eslint/no-require-imports */ /* eslint-disable @typescript-eslint/no-require-imports */
const { sanitizeInboundWebhookContent } = const { sanitizeInboundWebhookContent } =
@@ -236,7 +237,7 @@ export function useReplBridge(
sanitized = sanitizeInboundWebhookContent(sanitized) sanitized = sanitizeInboundWebhookContent(sanitized)
} }
} }
const content = await resolveAndPrepend(msg, sanitized) const content = await resolveAndPrepend(msg, sanitized as string | ContentBlockParam[])
const preview = const preview =
typeof content === 'string' typeof content === 'string'

View File

@@ -98,7 +98,7 @@ export function useSSHSession({
createToolStub(request.tool_name) createToolStub(request.tool_name)
const syntheticMessage = createSyntheticAssistantMessage( const syntheticMessage = createSyntheticAssistantMessage(
request, request as unknown as Parameters<typeof createSyntheticAssistantMessage>[0],
requestId, requestId,
) )

View File

@@ -14,6 +14,7 @@ import {
normalizeContentFromAPI, normalizeContentFromAPI,
normalizeMessagesForAPI, normalizeMessagesForAPI,
} from '../../../utils/messages.js' } from '../../../utils/messages.js'
import type { SDKAssistantMessageError } from '../../../entrypoints/agentSdkTypes.js'
import type { SystemPrompt } from '../../../utils/systemPromptType.js' import type { SystemPrompt } from '../../../utils/systemPromptType.js'
import type { ThinkingConfig } from '../../../utils/thinking.js' import type { ThinkingConfig } from '../../../utils/thinking.js'
import type { Options } from '../claude.js' import type { Options } from '../claude.js'
@@ -186,7 +187,7 @@ export async function* queryModelGemini(
yield createAssistantAPIErrorMessage({ yield createAssistantAPIErrorMessage({
content: `API Error: ${errorMessage}`, content: `API Error: ${errorMessage}`,
apiError: 'api_error', 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,
}) })
} }
} }

View File

@@ -28,7 +28,7 @@ export function getGrokClient(options?: {
maxRetries: options?.maxRetries ?? 0, maxRetries: options?.maxRetries ?? 0,
timeout: parseInt(process.env.API_TIMEOUT_MS || String(600 * 1000), 10), timeout: parseInt(process.env.API_TIMEOUT_MS || String(600 * 1000), 10),
dangerouslyAllowBrowser: true, dangerouslyAllowBrowser: true,
fetchOptions: getProxyFetchOptions({ forAnthropicAPI: false }) as RequestInit, fetchOptions: getProxyFetchOptions({ forAnthropicAPI: false }),
...(options?.fetchOverride && { fetch: options.fetchOverride }), ...(options?.fetchOverride && { fetch: options.fetchOverride }),
}) })

View File

@@ -12,6 +12,7 @@ import { anthropicToolsToOpenAI, anthropicToolChoiceToOpenAI } from '../openai/c
import { adaptOpenAIStreamToAnthropic } from '../openai/streamAdapter.js' import { adaptOpenAIStreamToAnthropic } from '../openai/streamAdapter.js'
import { resolveGrokModel } from './modelMapping.js' import { resolveGrokModel } from './modelMapping.js'
import { normalizeMessagesForAPI } from '../../../utils/messages.js' import { normalizeMessagesForAPI } from '../../../utils/messages.js'
import type { SDKAssistantMessageError } from '../../../entrypoints/agentSdkTypes.js'
import { toolToAPISchema } from '../../../utils/api.js' import { toolToAPISchema } from '../../../utils/api.js'
import { logForDebugging } from '../../../utils/debug.js' import { logForDebugging } from '../../../utils/debug.js'
import { addToTotalSessionCost } from '../../../cost-tracker.js' import { addToTotalSessionCost } from '../../../cost-tracker.js'
@@ -190,7 +191,7 @@ export async function* queryModelGrok(
yield createAssistantAPIErrorMessage({ yield createAssistantAPIErrorMessage({
content: `API Error: ${errorMessage}`, content: `API Error: ${errorMessage}`,
apiError: 'api_error', 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,
}) })
} }
} }

View File

@@ -151,7 +151,7 @@ describe('buildOpenAIRequestBody — thinking params', () => {
messages: [{ role: 'user', content: 'hello' }], messages: [{ role: 'user', content: 'hello' }],
tools: [] as any[], tools: [] as any[],
toolChoice: undefined as any, toolChoice: undefined as any,
} } as any
test('includes official DeepSeek API thinking format when enabled', () => { test('includes official DeepSeek API thinking format when enabled', () => {
const body = buildOpenAIRequestBody({ ...baseParams, enableThinking: true }) const body = buildOpenAIRequestBody({ ...baseParams, enableThinking: true })

View File

@@ -31,7 +31,7 @@ export function getOpenAIClient(options?: {
dangerouslyAllowBrowser: true, dangerouslyAllowBrowser: true,
...(process.env.OPENAI_ORG_ID && { organization: process.env.OPENAI_ORG_ID }), ...(process.env.OPENAI_ORG_ID && { organization: process.env.OPENAI_ORG_ID }),
...(process.env.OPENAI_PROJECT_ID && { project: process.env.OPENAI_PROJECT_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 }), ...(options?.fetchOverride && { fetch: options.fetchOverride }),
}) })

View File

@@ -36,6 +36,7 @@ import {
createAssistantAPIErrorMessage, createAssistantAPIErrorMessage,
normalizeContentFromAPI, normalizeContentFromAPI,
} from '../../../utils/messages.js' } from '../../../utils/messages.js'
import type { SDKAssistantMessageError } from '../../../entrypoints/agentSdkTypes.js'
import { import {
isToolSearchEnabled, isToolSearchEnabled,
extractDiscoveredToolNames, extractDiscoveredToolNames,
@@ -87,7 +88,11 @@ export function buildOpenAIRequestBody(params: {
toolChoice: any toolChoice: any
enableThinking: boolean enableThinking: boolean
temperatureOverride?: number temperatureOverride?: number
}): ChatCompletionCreateParamsStreaming { }): ChatCompletionCreateParamsStreaming & {
thinking?: { type: string }
enable_thinking?: boolean
chat_template_kwargs?: { thinking: boolean }
} {
const { model, messages, tools, toolChoice, enableThinking, temperatureOverride } = params const { model, messages, tools, toolChoice, enableThinking, temperatureOverride } = params
return { return {
model, model,
@@ -220,7 +225,7 @@ export async function* queryModelOpenAI(
// 10. Get client and make streaming request // 10. Get client and make streaming request
const client = getOpenAIClient({ const client = getOpenAIClient({
maxRetries: 0, maxRetries: 0,
fetchOverride: options.fetchOverride, fetchOverride: options.fetchOverride as unknown as typeof fetch,
source: options.querySource, source: options.querySource,
}) })
@@ -354,7 +359,7 @@ export async function* queryModelOpenAI(
yield createAssistantAPIErrorMessage({ yield createAssistantAPIErrorMessage({
content: `API Error: ${errorMessage}`, content: `API Error: ${errorMessage}`,
apiError: 'api_error', 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,
}) })
} }
} }

View File

@@ -49,6 +49,7 @@ import type {
import { inputSchema } from './AgentTool.js' import { inputSchema } from './AgentTool.js'
import { getAgentColor } from './agentColorManager.js' import { getAgentColor } from './agentColorManager.js'
import { GENERAL_PURPOSE_AGENT } from './built-in/generalPurposeAgent.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 const MAX_PROGRESS_MESSAGES_TO_SHOW = 3
@@ -411,7 +412,7 @@ export function renderToolResultMessage(
const finalAssistantMessage = createAssistantMessage({ const finalAssistantMessage = createAssistantMessage({
content: completionMessage, 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 ( return (

View File

@@ -131,10 +131,10 @@ export async function call<T = unknown>(
try { try {
const stdin = bridgeProc!.stdin const stdin = bridgeProc!.stdin
if (stdin) { if (stdin) {
const writable = stdin as Writable const writable = stdin as unknown as Writable
writable.write(JSON.stringify(req) + '\n') writable.write(JSON.stringify(req) + '\n')
if (typeof writable.flush === 'function') { if (typeof (writable as any).flush === 'function') {
writable.flush() (writable as any).flush()
} }
} }
} catch (err) { } catch (err) {
@@ -185,7 +185,7 @@ export function stopBridge(): void {
try { try {
const stdin = bridgeProc.stdin const stdin = bridgeProc.stdin
if (stdin) { if (stdin) {
const writable = stdin as Writable const writable = stdin as unknown as Writable
if (typeof writable.end === 'function') { if (typeof writable.end === 'function') {
writable.end() writable.end()
} }

View File

@@ -137,14 +137,14 @@ export function createStreamlinedTransformer(): (
): StdoutMessage | null { ): StdoutMessage | null {
switch (message.type) { switch (message.type) {
case 'assistant': { case 'assistant': {
const messageContent = (message as SDKAssistantMessage).message const messageContent = (message as unknown as SDKAssistantMessage).message
const content = messageContent?.content const content = messageContent?.content
const text = Array.isArray(content) const text = Array.isArray(content)
? extractTextContent(content, '\n').trim() ? extractTextContent(content, '\n').trim()
: '' : ''
// Accumulate tool counts from this message // Accumulate tool counts from this message
accumulateToolUses(message as SDKAssistantMessage, cumulativeCounts) accumulateToolUses(message as unknown as SDKAssistantMessage, cumulativeCounts)
if (text.length > 0) { if (text.length > 0) {
// Text message: emit text only, reset counts // Text message: emit text only, reset counts