mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-19 06:45:50 +00:00
feat: 全部类型问题解决
This commit is contained in:
@@ -93,8 +93,8 @@ describe("groupMessagesByApiRound", () => {
|
||||
test("preserves message order within groups", () => {
|
||||
const messages = [makeMsg("assistant", "a1"), makeMsg("user", "u2")];
|
||||
const groups = groupMessagesByApiRound(messages);
|
||||
expect(groups[0][0].message.id).toBe("a1");
|
||||
expect(groups[0][1].message.id).toBe("u2");
|
||||
expect(groups[0]![0]!.message!.id).toBe("a1");
|
||||
expect(groups[0]![1]!.message!.id).toBe("u2");
|
||||
});
|
||||
|
||||
test("handles system messages", () => {
|
||||
|
||||
@@ -39,6 +39,7 @@ import {
|
||||
getAgentListingDeltaAttachment,
|
||||
getDeferredToolsDeltaAttachment,
|
||||
getMcpInstructionsDeltaAttachment,
|
||||
type Attachment,
|
||||
} from '../../utils/attachments.js'
|
||||
import { getMemoryPath } from '../../utils/config.js'
|
||||
import { COMPACT_MAX_OUTPUT_TOKENS } from '../../utils/context.js'
|
||||
@@ -114,6 +115,7 @@ import {
|
||||
roughTokenCountEstimation,
|
||||
roughTokenCountEstimationForMessages,
|
||||
} from '../tokenEstimation.js'
|
||||
import type { SDKStatus } from '../../entrypoints/agentSdkTypes.js'
|
||||
import { groupMessagesByApiRound } from './grouping.js'
|
||||
import {
|
||||
getCompactPrompt,
|
||||
@@ -150,7 +152,7 @@ export function stripImagesFromMessages(messages: Message[]): Message[] {
|
||||
return message
|
||||
}
|
||||
|
||||
const content = message.message.content
|
||||
const content = message.message!.content
|
||||
if (!Array.isArray(content)) {
|
||||
return message
|
||||
}
|
||||
@@ -216,8 +218,8 @@ export function stripReinjectedAttachments(messages: Message[]): Message[] {
|
||||
m =>
|
||||
!(
|
||||
m.type === 'attachment' &&
|
||||
(m.attachment.type === 'skill_discovery' ||
|
||||
m.attachment.type === 'skill_listing')
|
||||
(m.attachment!.type === 'skill_discovery' ||
|
||||
m.attachment!.type === 'skill_listing')
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -251,8 +253,8 @@ export function truncateHeadForPTLRetry(
|
||||
// (drops only the marker, re-adds it, zero progress on retry 2+).
|
||||
const input =
|
||||
messages[0]?.type === 'user' &&
|
||||
messages[0].isMeta &&
|
||||
messages[0].message.content === PTL_RETRY_MARKER
|
||||
messages[0]?.isMeta &&
|
||||
messages[0]?.message?.content === PTL_RETRY_MARKER
|
||||
? messages.slice(1)
|
||||
: messages
|
||||
|
||||
@@ -760,7 +762,7 @@ export async function compactConversation(
|
||||
context.setStreamMode?.('requesting')
|
||||
context.setResponseLength?.(() => 0)
|
||||
context.onCompactProgress?.({ type: 'compact_end' })
|
||||
context.setSDKStatus?.(null)
|
||||
context.setSDKStatus?.("" as SDKStatus)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1103,7 +1105,7 @@ export async function partialCompactConversation(
|
||||
context.setStreamMode?.('requesting')
|
||||
context.setResponseLength?.(() => 0)
|
||||
context.onCompactProgress?.({ type: 'compact_end' })
|
||||
context.setSDKStatus?.(null)
|
||||
context.setSDKStatus?.("" as SDKStatus)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1453,7 +1455,7 @@ export async function createPostCompactFileAttachments(
|
||||
)
|
||||
|
||||
let usedTokens = 0
|
||||
return results.filter((result): result is AttachmentMessage => {
|
||||
return results.filter((result): result is AttachmentMessage<Attachment> => {
|
||||
if (result === null) {
|
||||
return false
|
||||
}
|
||||
@@ -1613,10 +1615,10 @@ export async function createAsyncAgentAttachmentsIfNeeded(
|
||||
function collectReadToolFilePaths(messages: Message[]): Set<string> {
|
||||
const stubIds = new Set<string>()
|
||||
for (const message of messages) {
|
||||
if (message.type !== 'user' || !Array.isArray(message.message.content)) {
|
||||
if (message.type !== 'user' || !Array.isArray(message.message!.content)) {
|
||||
continue
|
||||
}
|
||||
for (const block of message.message.content) {
|
||||
for (const block of message.message!.content) {
|
||||
if (
|
||||
block.type === 'tool_result' &&
|
||||
typeof block.content === 'string' &&
|
||||
@@ -1631,11 +1633,11 @@ function collectReadToolFilePaths(messages: Message[]): Set<string> {
|
||||
for (const message of messages) {
|
||||
if (
|
||||
message.type !== 'assistant' ||
|
||||
!Array.isArray(message.message.content)
|
||||
!Array.isArray(message.message!.content)
|
||||
) {
|
||||
continue
|
||||
}
|
||||
for (const block of message.message.content) {
|
||||
for (const block of message.message!.content) {
|
||||
if (
|
||||
block.type !== 'tool_use' ||
|
||||
block.name !== FILE_READ_TOOL_NAME ||
|
||||
|
||||
@@ -43,7 +43,7 @@ export function groupMessagesByApiRound(messages: Message[]): Message[][] {
|
||||
for (const msg of messages) {
|
||||
if (
|
||||
msg.type === 'assistant' &&
|
||||
msg.message.id !== lastAssistantId &&
|
||||
msg.message!.id !== lastAssistantId &&
|
||||
current.length > 0
|
||||
) {
|
||||
groups.push(current)
|
||||
@@ -52,7 +52,7 @@ export function groupMessagesByApiRound(messages: Message[]): Message[][] {
|
||||
current.push(msg)
|
||||
}
|
||||
if (msg.type === 'assistant') {
|
||||
lastAssistantId = msg.message.id
|
||||
lastAssistantId = msg.message!.id
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -169,11 +169,11 @@ export function estimateMessageTokens(messages: Message[]): number {
|
||||
continue
|
||||
}
|
||||
|
||||
if (!Array.isArray(message.message.content)) {
|
||||
if (!Array.isArray(message.message!.content)) {
|
||||
continue
|
||||
}
|
||||
|
||||
for (const block of message.message.content) {
|
||||
for (const block of message.message!.content) {
|
||||
if (block.type === 'text') {
|
||||
totalTokens += roughTokenCountEstimation(block.text)
|
||||
} else if (block.type === 'tool_result') {
|
||||
@@ -228,9 +228,9 @@ function collectCompactableToolIds(messages: Message[]): string[] {
|
||||
for (const message of messages) {
|
||||
if (
|
||||
message.type === 'assistant' &&
|
||||
Array.isArray(message.message.content)
|
||||
Array.isArray(message.message!.content)
|
||||
) {
|
||||
for (const block of message.message.content) {
|
||||
for (const block of message.message!.content) {
|
||||
if (block.type === 'tool_use' && COMPACTABLE_TOOLS.has(block.name)) {
|
||||
ids.push(block.id)
|
||||
}
|
||||
@@ -313,9 +313,9 @@ async function cachedMicrocompactPath(
|
||||
const compactableToolIds = new Set(collectCompactableToolIds(messages))
|
||||
// Second pass: register tool results grouped by user message
|
||||
for (const message of messages) {
|
||||
if (message.type === 'user' && Array.isArray(message.message.content)) {
|
||||
if (message.type === 'user' && Array.isArray(message.message!.content)) {
|
||||
const groupIds: string[] = []
|
||||
for (const block of message.message.content) {
|
||||
for (const block of message.message!.content) {
|
||||
if (
|
||||
block.type === 'tool_result' &&
|
||||
compactableToolIds.has(block.tool_use_id) &&
|
||||
@@ -375,7 +375,7 @@ async function cachedMicrocompactPath(
|
||||
const baseline =
|
||||
lastAsst?.type === 'assistant'
|
||||
? ((
|
||||
lastAsst.message.usage as unknown as Record<
|
||||
lastAsst.message!.usage as unknown as Record<
|
||||
string,
|
||||
number | undefined
|
||||
>
|
||||
@@ -468,11 +468,11 @@ function maybeTimeBasedMicrocompact(
|
||||
|
||||
let tokensSaved = 0
|
||||
const result: Message[] = messages.map(message => {
|
||||
if (message.type !== 'user' || !Array.isArray(message.message.content)) {
|
||||
if (message.type !== 'user' || !Array.isArray(message.message!.content)) {
|
||||
return message
|
||||
}
|
||||
let touched = false
|
||||
const newContent = message.message.content.map(block => {
|
||||
const newContent = message.message!.content.map(block => {
|
||||
if (
|
||||
block.type === 'tool_result' &&
|
||||
clearSet.has(block.tool_use_id) &&
|
||||
|
||||
@@ -134,11 +134,11 @@ async function initSessionMemoryCompactConfig(): Promise<void> {
|
||||
*/
|
||||
export function hasTextBlocks(message: Message): boolean {
|
||||
if (message.type === 'assistant') {
|
||||
const content = message.message.content
|
||||
const content = message.message!.content
|
||||
return Array.isArray(content) && content.some(block => block.type === 'text')
|
||||
}
|
||||
if (message.type === 'user') {
|
||||
const content = message.message.content
|
||||
const content = message.message!.content
|
||||
if (typeof content === 'string') {
|
||||
return content.length > 0
|
||||
}
|
||||
@@ -156,7 +156,7 @@ function getToolResultIds(message: Message): string[] {
|
||||
if (message.type !== 'user') {
|
||||
return []
|
||||
}
|
||||
const content = message.message.content
|
||||
const content = message.message!.content
|
||||
if (!Array.isArray(content)) {
|
||||
return []
|
||||
}
|
||||
@@ -176,7 +176,7 @@ function hasToolUseWithIds(message: Message, toolUseIds: Set<string>): boolean {
|
||||
if (message.type !== 'assistant') {
|
||||
return false
|
||||
}
|
||||
const content = message.message.content
|
||||
const content = message.message!.content
|
||||
if (!Array.isArray(content)) {
|
||||
return false
|
||||
}
|
||||
@@ -251,8 +251,8 @@ export function adjustIndexToPreserveAPIInvariants(
|
||||
const toolUseIdsInKeptRange = new Set<string>()
|
||||
for (let i = adjustedIndex; i < messages.length; i++) {
|
||||
const msg = messages[i]!
|
||||
if (msg.type === 'assistant' && Array.isArray(msg.message.content)) {
|
||||
for (const block of msg.message.content) {
|
||||
if (msg.type === 'assistant' && Array.isArray(msg.message!.content)) {
|
||||
for (const block of msg.message!.content) {
|
||||
if (block.type === 'tool_use') {
|
||||
toolUseIdsInKeptRange.add(block.id)
|
||||
}
|
||||
@@ -273,9 +273,9 @@ export function adjustIndexToPreserveAPIInvariants(
|
||||
// Remove found tool_use_ids from the set
|
||||
if (
|
||||
message.type === 'assistant' &&
|
||||
Array.isArray(message.message.content)
|
||||
Array.isArray(message.message!.content)
|
||||
) {
|
||||
for (const block of message.message.content) {
|
||||
for (const block of message.message!.content) {
|
||||
if (block.type === 'tool_use' && neededToolUseIds.has(block.id)) {
|
||||
neededToolUseIds.delete(block.id)
|
||||
}
|
||||
@@ -290,8 +290,8 @@ export function adjustIndexToPreserveAPIInvariants(
|
||||
const messageIdsInKeptRange = new Set<string>()
|
||||
for (let i = adjustedIndex; i < messages.length; i++) {
|
||||
const msg = messages[i]!
|
||||
if (msg.type === 'assistant' && msg.message.id) {
|
||||
messageIdsInKeptRange.add(msg.message.id)
|
||||
if (msg.type === 'assistant' && msg.message!.id) {
|
||||
messageIdsInKeptRange.add(msg.message!.id)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,8 +301,8 @@ export function adjustIndexToPreserveAPIInvariants(
|
||||
const message = messages[i]!
|
||||
if (
|
||||
message.type === 'assistant' &&
|
||||
message.message.id &&
|
||||
messageIdsInKeptRange.has(message.message.id)
|
||||
message.message!.id &&
|
||||
messageIdsInKeptRange.has(message.message!.id)
|
||||
) {
|
||||
// This message has the same message.id as one in the kept range
|
||||
// Include it so thinking blocks can be properly merged
|
||||
|
||||
Reference in New Issue
Block a user