Kode-cli/src/utils/ask.tsx
CrazyBoyM 6cf566fb40 feat: Add comprehensive GPT-5 support with Responses API integration
- Add GPT-5 model definitions (gpt-5, gpt-5-mini, gpt-5-nano, gpt-5-chat-latest)
- Implement GPT-5 Responses API support with intelligent fallback to Chat Completions
- Add GPT-5 specific parameter handling (max_completion_tokens, temperature=1)
- Support custom tools and freeform function calling capabilities
- Add reasoning effort and verbosity control parameters
- Implement GPT-5 connection testing service
- Add model capability detection and automatic parameter transformation
- Support both official OpenAI and third-party GPT-5 providers
- Add todo list and sticker request UI components
- Improve notebook support with better type definitions
- Enhance debug logging and error handling for GPT-5
- Update model selector with GPT-5 compatibility checks

This commit provides full GPT-5 support while maintaining backward compatibility with existing models.
2025-08-13 01:38:15 +08:00

100 lines
2.5 KiB
TypeScript

import { last } from 'lodash-es'
import { Command } from '../commands'
import { getSystemPrompt } from '../constants/prompts'
import { getContext } from '../context'
import { getTotalCost } from '../cost-tracker'
import { Message, query } from '../query'
import { CanUseToolFn } from '../hooks/useCanUseTool'
import { Tool } from '../Tool'
import { getModelManager } from '../utils/model'
import { setCwd } from './state'
import { getMessagesPath, overwriteLog } from './log'
import { createUserMessage } from './messages'
type Props = {
commands: Command[]
safeMode?: boolean
hasPermissionsToUseTool: CanUseToolFn
messageLogName: string
prompt: string
cwd: string
tools: Tool[]
verbose?: boolean
}
// Sends a single prompt to the Claude API and returns the response.
// Assumes that claude is being used non-interactively -- will not
// ask the user for permissions or further input.
export async function ask({
commands,
safeMode,
hasPermissionsToUseTool,
messageLogName,
prompt,
cwd,
tools,
verbose = false,
}: Props): Promise<{
resultText: string
totalCost: number
messageHistoryFile: string
}> {
await setCwd(cwd)
const message = createUserMessage(prompt)
const messages: Message[] = [message]
const [systemPrompt, context, model] = await Promise.all([
getSystemPrompt(),
getContext(),
getModelManager().getModelName('main'),
])
for await (const m of query(
messages,
systemPrompt,
context,
hasPermissionsToUseTool,
{
options: {
commands,
tools,
verbose,
safeMode,
forkNumber: 0,
messageLogName: 'unused',
maxThinkingTokens: 0,
},
abortController: new AbortController(),
messageId: undefined,
readFileTimestamps: {},
setToolJSX: () => {}, // No-op function for non-interactive use
},
)) {
messages.push(m)
}
const result = last(messages)
if (!result || result.type !== 'assistant') {
throw new Error('Expected content to be an assistant message')
}
if (result.message.content[0]?.type !== 'text') {
throw new Error(
`Expected first content item to be text, but got ${JSON.stringify(
result.message.content[0],
null,
2,
)}`,
)
}
// Write log that can be retrieved with `claude log`
const messageHistoryFile = getMessagesPath(messageLogName, 0, 0)
overwriteLog(messageHistoryFile, messages)
return {
resultText: result.message.content[0].text,
totalCost: getTotalCost(),
messageHistoryFile,
}
}