import type { ContentBlockParam } from '@anthropic-ai/sdk/resources'import { randomUUID } from 'crypto'import { setPromptId } from 'src/bootstrap/state.js'import type {AttachmentMessage,SystemMessage,UserMessage,} from 'src/types/message.js'import { logEvent } from '../../services/analytics/index.js'import type { PermissionMode } from '../../types/permissions.js'import { createUserMessage } from '../messages.js'import { logOTelEvent, redactIfDisabled } from '../telemetry/events.js'import { startInteractionSpan } from '../telemetry/sessionTracing.js'import {matchesKeepGoingKeyword,matchesNegativeKeyword,} from '../userPromptKeywords.js'export function processTextPrompt(input: string | Array<ContentBlockParam>,imageContentBlocks: ContentBlockParam[],imagePasteIds: number[],attachmentMessages: AttachmentMessage[],uuid?: string,permissionMode?: PermissionMode,isMeta?: boolean,): {messages: (UserMessage | AttachmentMessage | SystemMessage)[]shouldQuery: boolean} {const promptId = randomUUID()setPromptId(promptId)const userPromptText =typeof input === 'string'? input: input.find(block => block.type === 'text')?.text || ''startInteractionSpan(userPromptText)// Emit user_prompt OTEL event for both string (CLI) and array (SDK/VS Code)// input shapes. Previously gated on `typeof input === 'string'`, so VS Code// sessions never emitted user_prompt (anthropics/claude-code#33301).// For array input, use the LAST text block: createUserContent pushes the// user's message last (after any <ide_selection>/attachment context blocks),// so .findLast gets the actual prompt. userPromptText (first block) is kept// unchanged for startInteractionSpan to preserve existing span attributes.const otelPromptText =typeof input === 'string'? input: input.findLast(block => block.type === 'text')?.text || ''if (otelPromptText) {void logOTelEvent('user_prompt', {prompt_length: String(otelPromptText.length),prompt: redactIfDisabled(otelPromptText),'prompt.id': promptId,})}const isNegative = matchesNegativeKeyword(userPromptText)const isKeepGoing = matchesKeepGoingKeyword(userPromptText)logEvent('tengu_input_prompt', {is_negative: isNegative,is_keep_going: isKeepGoing,})// If we have pasted images, create a message with image contentif (imageContentBlocks.length > 0) {// Build content: text first, then images belowconst textContent =typeof input === 'string'? input.trim()? [{ type: 'text' as const, text: input }]: []: inputconst userMessage = createUserMessage({content: [...textContent, ...imageContentBlocks],uuid: uuid,imagePasteIds: imagePasteIds.length > 0 ? imagePasteIds : undefined,permissionMode,isMeta: isMeta || undefined,})return {messages: [userMessage, ...attachmentMessages],shouldQuery: true,}}const userMessage = createUserMessage({content: input,uuid,permissionMode,isMeta: isMeta || undefined,})return {messages: [userMessage, ...attachmentMessages],shouldQuery: true,}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。