mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-18 14:25:51 +00:00
style: 完成所有文件的lint
This commit is contained in:
@@ -1,121 +1,115 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { groupMessagesByApiRound } from "../grouping";
|
||||
import { describe, expect, test } from 'bun:test'
|
||||
import { groupMessagesByApiRound } from '../grouping'
|
||||
|
||||
function makeMsg(type: "user" | "assistant" | "system", id: string): any {
|
||||
function makeMsg(type: 'user' | 'assistant' | 'system', id: string): any {
|
||||
return {
|
||||
type,
|
||||
message: { id, content: `${type}-${id}` },
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
describe("groupMessagesByApiRound", () => {
|
||||
describe('groupMessagesByApiRound', () => {
|
||||
// Boundary fires when: assistant msg with NEW id AND current group has items
|
||||
test("splits before first assistant if user messages precede it", () => {
|
||||
const messages = [makeMsg("user", "u1"), makeMsg("assistant", "a1")];
|
||||
const groups = groupMessagesByApiRound(messages);
|
||||
test('splits before first assistant if user messages precede it', () => {
|
||||
const messages = [makeMsg('user', 'u1'), makeMsg('assistant', 'a1')]
|
||||
const groups = groupMessagesByApiRound(messages)
|
||||
// user msgs form group 1, assistant starts group 2
|
||||
expect(groups).toHaveLength(2);
|
||||
expect(groups[0]).toHaveLength(1);
|
||||
expect(groups[1]).toHaveLength(1);
|
||||
});
|
||||
expect(groups).toHaveLength(2)
|
||||
expect(groups[0]).toHaveLength(1)
|
||||
expect(groups[1]).toHaveLength(1)
|
||||
})
|
||||
|
||||
test("single assistant message forms one group", () => {
|
||||
const messages = [makeMsg("assistant", "a1")];
|
||||
const groups = groupMessagesByApiRound(messages);
|
||||
expect(groups).toHaveLength(1);
|
||||
});
|
||||
test('single assistant message forms one group', () => {
|
||||
const messages = [makeMsg('assistant', 'a1')]
|
||||
const groups = groupMessagesByApiRound(messages)
|
||||
expect(groups).toHaveLength(1)
|
||||
})
|
||||
|
||||
test("splits at new assistant message ID", () => {
|
||||
test('splits at new assistant message ID', () => {
|
||||
const messages = [
|
||||
makeMsg("user", "u1"),
|
||||
makeMsg("assistant", "a1"),
|
||||
makeMsg("assistant", "a2"),
|
||||
];
|
||||
const groups = groupMessagesByApiRound(messages);
|
||||
expect(groups).toHaveLength(3);
|
||||
});
|
||||
makeMsg('user', 'u1'),
|
||||
makeMsg('assistant', 'a1'),
|
||||
makeMsg('assistant', 'a2'),
|
||||
]
|
||||
const groups = groupMessagesByApiRound(messages)
|
||||
expect(groups).toHaveLength(3)
|
||||
})
|
||||
|
||||
test("keeps same-ID assistant messages in same group (streaming chunks)", () => {
|
||||
test('keeps same-ID assistant messages in same group (streaming chunks)', () => {
|
||||
const messages = [
|
||||
makeMsg("assistant", "a1"),
|
||||
makeMsg("assistant", "a1"),
|
||||
makeMsg("assistant", "a1"),
|
||||
];
|
||||
const groups = groupMessagesByApiRound(messages);
|
||||
expect(groups).toHaveLength(1);
|
||||
expect(groups[0]).toHaveLength(3);
|
||||
});
|
||||
makeMsg('assistant', 'a1'),
|
||||
makeMsg('assistant', 'a1'),
|
||||
makeMsg('assistant', 'a1'),
|
||||
]
|
||||
const groups = groupMessagesByApiRound(messages)
|
||||
expect(groups).toHaveLength(1)
|
||||
expect(groups[0]).toHaveLength(3)
|
||||
})
|
||||
|
||||
test("returns empty array for empty input", () => {
|
||||
expect(groupMessagesByApiRound([])).toEqual([]);
|
||||
});
|
||||
test('returns empty array for empty input', () => {
|
||||
expect(groupMessagesByApiRound([])).toEqual([])
|
||||
})
|
||||
|
||||
test("handles all user messages (no assistant)", () => {
|
||||
const messages = [makeMsg("user", "u1"), makeMsg("user", "u2")];
|
||||
const groups = groupMessagesByApiRound(messages);
|
||||
expect(groups).toHaveLength(1);
|
||||
});
|
||||
test('handles all user messages (no assistant)', () => {
|
||||
const messages = [makeMsg('user', 'u1'), makeMsg('user', 'u2')]
|
||||
const groups = groupMessagesByApiRound(messages)
|
||||
expect(groups).toHaveLength(1)
|
||||
})
|
||||
|
||||
test("three API rounds produce correct groups", () => {
|
||||
test('three API rounds produce correct groups', () => {
|
||||
const messages = [
|
||||
makeMsg("user", "u1"),
|
||||
makeMsg("assistant", "a1"),
|
||||
makeMsg("user", "u2"),
|
||||
makeMsg("assistant", "a2"),
|
||||
makeMsg("user", "u3"),
|
||||
makeMsg("assistant", "a3"),
|
||||
];
|
||||
const groups = groupMessagesByApiRound(messages);
|
||||
makeMsg('user', 'u1'),
|
||||
makeMsg('assistant', 'a1'),
|
||||
makeMsg('user', 'u2'),
|
||||
makeMsg('assistant', 'a2'),
|
||||
makeMsg('user', 'u3'),
|
||||
makeMsg('assistant', 'a3'),
|
||||
]
|
||||
const groups = groupMessagesByApiRound(messages)
|
||||
// [u1], [a1, u2], [a2, u3], [a3] = 4 groups
|
||||
expect(groups).toHaveLength(4);
|
||||
});
|
||||
expect(groups).toHaveLength(4)
|
||||
})
|
||||
|
||||
test("consecutive user messages stay in same group", () => {
|
||||
const messages = [makeMsg("user", "u1"), makeMsg("user", "u2")];
|
||||
expect(groupMessagesByApiRound(messages)).toHaveLength(1);
|
||||
});
|
||||
test('consecutive user messages stay in same group', () => {
|
||||
const messages = [makeMsg('user', 'u1'), makeMsg('user', 'u2')]
|
||||
expect(groupMessagesByApiRound(messages)).toHaveLength(1)
|
||||
})
|
||||
|
||||
test("does not produce empty groups", () => {
|
||||
const messages = [
|
||||
makeMsg("assistant", "a1"),
|
||||
makeMsg("assistant", "a2"),
|
||||
];
|
||||
const groups = groupMessagesByApiRound(messages);
|
||||
test('does not produce empty groups', () => {
|
||||
const messages = [makeMsg('assistant', 'a1'), makeMsg('assistant', 'a2')]
|
||||
const groups = groupMessagesByApiRound(messages)
|
||||
for (const group of groups) {
|
||||
expect(group.length).toBeGreaterThan(0);
|
||||
expect(group.length).toBeGreaterThan(0)
|
||||
}
|
||||
});
|
||||
})
|
||||
|
||||
test("handles single message", () => {
|
||||
expect(groupMessagesByApiRound([makeMsg("user", "u1")])).toHaveLength(1);
|
||||
});
|
||||
test('handles single message', () => {
|
||||
expect(groupMessagesByApiRound([makeMsg('user', 'u1')])).toHaveLength(1)
|
||||
})
|
||||
|
||||
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");
|
||||
});
|
||||
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')
|
||||
})
|
||||
|
||||
test("handles system messages", () => {
|
||||
const messages = [
|
||||
makeMsg("system", "s1"),
|
||||
makeMsg("assistant", "a1"),
|
||||
];
|
||||
test('handles system messages', () => {
|
||||
const messages = [makeMsg('system', 's1'), makeMsg('assistant', 'a1')]
|
||||
// system msg is non-assistant, goes to current. Then assistant a1 is new ID
|
||||
// and current has items, so split.
|
||||
const groups = groupMessagesByApiRound(messages);
|
||||
expect(groups).toHaveLength(2);
|
||||
});
|
||||
const groups = groupMessagesByApiRound(messages)
|
||||
expect(groups).toHaveLength(2)
|
||||
})
|
||||
|
||||
test("tool_result after assistant stays in same round", () => {
|
||||
test('tool_result after assistant stays in same round', () => {
|
||||
const messages = [
|
||||
makeMsg("assistant", "a1"),
|
||||
makeMsg("user", "tool_result_1"),
|
||||
makeMsg("assistant", "a1"), // same ID = no new boundary
|
||||
];
|
||||
const groups = groupMessagesByApiRound(messages);
|
||||
expect(groups).toHaveLength(1);
|
||||
expect(groups[0]).toHaveLength(3);
|
||||
});
|
||||
});
|
||||
makeMsg('assistant', 'a1'),
|
||||
makeMsg('user', 'tool_result_1'),
|
||||
makeMsg('assistant', 'a1'), // same ID = no new boundary
|
||||
]
|
||||
const groups = groupMessagesByApiRound(messages)
|
||||
expect(groups).toHaveLength(1)
|
||||
expect(groups[0]).toHaveLength(3)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,77 +1,80 @@
|
||||
import { mock, describe, expect, test } from "bun:test";
|
||||
import { mock, describe, expect, test } from 'bun:test'
|
||||
|
||||
mock.module("bun:bundle", () => ({ feature: () => false }));
|
||||
mock.module('bun:bundle', () => ({ feature: () => false }))
|
||||
|
||||
const { formatCompactSummary } = await import("../prompt");
|
||||
const { formatCompactSummary } = await import('../prompt')
|
||||
|
||||
describe("formatCompactSummary", () => {
|
||||
test("strips <analysis>...</analysis> block", () => {
|
||||
const input = "<analysis>my thought process</analysis>\n<summary>the summary</summary>";
|
||||
const result = formatCompactSummary(input);
|
||||
expect(result).not.toContain("<analysis>");
|
||||
expect(result).not.toContain("my thought process");
|
||||
});
|
||||
describe('formatCompactSummary', () => {
|
||||
test('strips <analysis>...</analysis> block', () => {
|
||||
const input =
|
||||
'<analysis>my thought process</analysis>\n<summary>the summary</summary>'
|
||||
const result = formatCompactSummary(input)
|
||||
expect(result).not.toContain('<analysis>')
|
||||
expect(result).not.toContain('my thought process')
|
||||
})
|
||||
|
||||
test("replaces <summary>...</summary> with 'Summary:\\n' prefix", () => {
|
||||
const input = "<summary>key points here</summary>";
|
||||
const result = formatCompactSummary(input);
|
||||
expect(result).toContain("Summary:");
|
||||
expect(result).toContain("key points here");
|
||||
expect(result).not.toContain("<summary>");
|
||||
});
|
||||
const input = '<summary>key points here</summary>'
|
||||
const result = formatCompactSummary(input)
|
||||
expect(result).toContain('Summary:')
|
||||
expect(result).toContain('key points here')
|
||||
expect(result).not.toContain('<summary>')
|
||||
})
|
||||
|
||||
test("handles analysis + summary together", () => {
|
||||
const input = "<analysis>thinking</analysis><summary>result</summary>";
|
||||
const result = formatCompactSummary(input);
|
||||
expect(result).not.toContain("thinking");
|
||||
expect(result).toContain("result");
|
||||
});
|
||||
test('handles analysis + summary together', () => {
|
||||
const input = '<analysis>thinking</analysis><summary>result</summary>'
|
||||
const result = formatCompactSummary(input)
|
||||
expect(result).not.toContain('thinking')
|
||||
expect(result).toContain('result')
|
||||
})
|
||||
|
||||
test("handles summary without analysis", () => {
|
||||
const input = "<summary>just the summary</summary>";
|
||||
const result = formatCompactSummary(input);
|
||||
expect(result).toContain("just the summary");
|
||||
});
|
||||
test('handles summary without analysis', () => {
|
||||
const input = '<summary>just the summary</summary>'
|
||||
const result = formatCompactSummary(input)
|
||||
expect(result).toContain('just the summary')
|
||||
})
|
||||
|
||||
test("handles analysis without summary", () => {
|
||||
const input = "<analysis>just analysis</analysis>and some text";
|
||||
const result = formatCompactSummary(input);
|
||||
expect(result).not.toContain("just analysis");
|
||||
expect(result).toContain("and some text");
|
||||
});
|
||||
test('handles analysis without summary', () => {
|
||||
const input = '<analysis>just analysis</analysis>and some text'
|
||||
const result = formatCompactSummary(input)
|
||||
expect(result).not.toContain('just analysis')
|
||||
expect(result).toContain('and some text')
|
||||
})
|
||||
|
||||
test("collapses multiple newlines to double", () => {
|
||||
const input = "hello\n\n\n\nworld";
|
||||
const result = formatCompactSummary(input);
|
||||
expect(result).not.toMatch(/\n{3,}/);
|
||||
});
|
||||
test('collapses multiple newlines to double', () => {
|
||||
const input = 'hello\n\n\n\nworld'
|
||||
const result = formatCompactSummary(input)
|
||||
expect(result).not.toMatch(/\n{3,}/)
|
||||
})
|
||||
|
||||
test("trims leading/trailing whitespace", () => {
|
||||
const input = " \n hello \n ";
|
||||
const result = formatCompactSummary(input);
|
||||
expect(result).toBe("hello");
|
||||
});
|
||||
test('trims leading/trailing whitespace', () => {
|
||||
const input = ' \n hello \n '
|
||||
const result = formatCompactSummary(input)
|
||||
expect(result).toBe('hello')
|
||||
})
|
||||
|
||||
test("handles empty string", () => {
|
||||
expect(formatCompactSummary("")).toBe("");
|
||||
});
|
||||
test('handles empty string', () => {
|
||||
expect(formatCompactSummary('')).toBe('')
|
||||
})
|
||||
|
||||
test("handles plain text without tags", () => {
|
||||
const input = "just plain text";
|
||||
expect(formatCompactSummary(input)).toBe("just plain text");
|
||||
});
|
||||
test('handles plain text without tags', () => {
|
||||
const input = 'just plain text'
|
||||
expect(formatCompactSummary(input)).toBe('just plain text')
|
||||
})
|
||||
|
||||
test("handles multiline analysis content", () => {
|
||||
const input = "<analysis>\nline1\nline2\nline3\n</analysis><summary>ok</summary>";
|
||||
const result = formatCompactSummary(input);
|
||||
expect(result).not.toContain("line1");
|
||||
expect(result).toContain("ok");
|
||||
});
|
||||
test('handles multiline analysis content', () => {
|
||||
const input =
|
||||
'<analysis>\nline1\nline2\nline3\n</analysis><summary>ok</summary>'
|
||||
const result = formatCompactSummary(input)
|
||||
expect(result).not.toContain('line1')
|
||||
expect(result).toContain('ok')
|
||||
})
|
||||
|
||||
test("preserves content between analysis and summary", () => {
|
||||
const input = "<analysis>thoughts</analysis>middle text<summary>final</summary>";
|
||||
const result = formatCompactSummary(input);
|
||||
expect(result).toContain("middle text");
|
||||
expect(result).toContain("final");
|
||||
});
|
||||
});
|
||||
test('preserves content between analysis and summary', () => {
|
||||
const input =
|
||||
'<analysis>thoughts</analysis>middle text<summary>final</summary>'
|
||||
const result = formatCompactSummary(input)
|
||||
expect(result).toContain('middle text')
|
||||
expect(result).toContain('final')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -38,10 +38,7 @@ function makeSystemMessage(
|
||||
return msg
|
||||
}
|
||||
|
||||
function makeSnipBoundary(
|
||||
uuid: string,
|
||||
removedUuids: string[],
|
||||
): Message {
|
||||
function makeSnipBoundary(uuid: string, removedUuids: string[]): Message {
|
||||
return makeSystemMessage(uuid, 'snip_boundary', {
|
||||
snipMetadata: { removedUuids },
|
||||
content: '[snip] Conversation history before this point has been snipped.',
|
||||
@@ -126,7 +123,7 @@ describe('snipCompactIfNeeded', () => {
|
||||
|
||||
expect(result.executed).toBe(true)
|
||||
expect(result.messages).toHaveLength(2)
|
||||
expect(result.messages.map((m) => m.uuid) as string[]).toEqual(['c', 'bnd'])
|
||||
expect(result.messages.map(m => m.uuid) as string[]).toEqual(['c', 'bnd'])
|
||||
expect(result.tokensFreed).toBeGreaterThan(0)
|
||||
expect(result.boundaryMessage).toBe(boundary)
|
||||
})
|
||||
@@ -154,7 +151,7 @@ describe('snipCompactIfNeeded', () => {
|
||||
|
||||
expect(result.executed).toBe(true)
|
||||
expect(result.messages).toHaveLength(2)
|
||||
expect(result.messages.map((m) => m.uuid) as string[]).toEqual(['bnd', 'c'])
|
||||
expect(result.messages.map(m => m.uuid) as string[]).toEqual(['bnd', 'c'])
|
||||
})
|
||||
|
||||
test('handles empty removedUuids array', () => {
|
||||
@@ -183,7 +180,12 @@ describe('snipCompactIfNeeded', () => {
|
||||
expect(result.executed).toBe(true)
|
||||
expect(result.boundaryMessage!.uuid as string).toBe('bnd2')
|
||||
// 'b' removed by boundary2, 'a' not in boundary2's removedUuids
|
||||
expect(result.messages.map((m) => m.uuid) as string[]).toEqual(['a', 'bnd1', 'bnd2', 'c'])
|
||||
expect(result.messages.map(m => m.uuid) as string[]).toEqual([
|
||||
'a',
|
||||
'bnd1',
|
||||
'bnd2',
|
||||
'c',
|
||||
])
|
||||
})
|
||||
|
||||
test('respects force option (no functional difference — both execute)', () => {
|
||||
|
||||
@@ -32,10 +32,7 @@ function makeSystemMessage(
|
||||
return msg
|
||||
}
|
||||
|
||||
function makeSnipBoundary(
|
||||
uuid: string,
|
||||
removedUuids: string[],
|
||||
): Message {
|
||||
function makeSnipBoundary(uuid: string, removedUuids: string[]): Message {
|
||||
return makeSystemMessage(uuid, 'snip_boundary', {
|
||||
snipMetadata: { removedUuids },
|
||||
content: '[snip]',
|
||||
@@ -87,7 +84,7 @@ describe('projectSnippedView', () => {
|
||||
const boundary = makeSnipBoundary('bnd', ['a', 'c'])
|
||||
|
||||
const result = projectSnippedView([a, b, c, boundary])
|
||||
expect(result.map((m) => m.uuid) as string[]).toEqual(['b', 'bnd'])
|
||||
expect(result.map(m => m.uuid) as string[]).toEqual(['b', 'bnd'])
|
||||
})
|
||||
|
||||
test('preserves boundary messages themselves', () => {
|
||||
@@ -108,7 +105,12 @@ describe('projectSnippedView', () => {
|
||||
const boundary2 = makeSnipBoundary('bnd2', ['c'])
|
||||
|
||||
const result = projectSnippedView([a, boundary1, b, c, boundary2, d])
|
||||
expect(result.map((m) => m.uuid) as string[]).toEqual(['bnd1', 'b', 'bnd2', 'd'])
|
||||
expect(result.map(m => m.uuid) as string[]).toEqual([
|
||||
'bnd1',
|
||||
'b',
|
||||
'bnd2',
|
||||
'd',
|
||||
])
|
||||
})
|
||||
|
||||
test('returns all messages when boundary has empty removedUuids', () => {
|
||||
@@ -116,7 +118,7 @@ describe('projectSnippedView', () => {
|
||||
const boundary = makeSnipBoundary('bnd', [])
|
||||
|
||||
const result = projectSnippedView([a, boundary])
|
||||
expect(result.map((m) => m.uuid) as string[]).toEqual(['a', 'bnd'])
|
||||
expect(result.map(m => m.uuid) as string[]).toEqual(['a', 'bnd'])
|
||||
})
|
||||
|
||||
test('handles empty message array', () => {
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
// Auto-generated stub — replace with real implementation
|
||||
export {};
|
||||
export const getCachedMCConfig: () => { enabled?: boolean; systemPromptSuggestSummaries?: boolean; supportedModels?: string[]; [key: string]: unknown } = () => ({});
|
||||
export {}
|
||||
export const getCachedMCConfig: () => {
|
||||
enabled?: boolean
|
||||
systemPromptSuggestSummaries?: boolean
|
||||
supportedModels?: string[]
|
||||
[key: string]: unknown
|
||||
} = () => ({})
|
||||
|
||||
@@ -267,7 +267,9 @@ export function truncateHeadForPTLRetry(
|
||||
let acc = 0
|
||||
dropCount = 0
|
||||
for (const g of groups) {
|
||||
acc += roughTokenCountEstimationForMessages(g as Parameters<typeof roughTokenCountEstimationForMessages>[0])
|
||||
acc += roughTokenCountEstimationForMessages(
|
||||
g as Parameters<typeof roughTokenCountEstimationForMessages>[0],
|
||||
)
|
||||
dropCount++
|
||||
if (acc >= tokenGap) break
|
||||
}
|
||||
@@ -762,7 +764,7 @@ export async function compactConversation(
|
||||
context.setStreamMode?.('requesting')
|
||||
context.setResponseLength?.(() => 0)
|
||||
context.onCompactProgress?.({ type: 'compact_end' })
|
||||
context.setSDKStatus?.("" as SDKStatus)
|
||||
context.setSDKStatus?.('' as SDKStatus)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1105,7 +1107,7 @@ export async function partialCompactConversation(
|
||||
context.setStreamMode?.('requesting')
|
||||
context.setResponseLength?.(() => 0)
|
||||
context.onCompactProgress?.({ type: 'compact_end' })
|
||||
context.setSDKStatus?.("" as SDKStatus)
|
||||
context.setSDKStatus?.('' as SDKStatus)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1333,8 +1335,18 @@ async function streamCompactSummary({
|
||||
let next = await streamIter.next()
|
||||
|
||||
while (!next.done) {
|
||||
const event = next.value as StreamEvent | AssistantMessage | SystemAPIErrorMessage
|
||||
const streamEvent = event as { type: string; event: { type: string; content_block: { type: string }; delta: { type: string; text: string } } }
|
||||
const event = next.value as
|
||||
| StreamEvent
|
||||
| AssistantMessage
|
||||
| SystemAPIErrorMessage
|
||||
const streamEvent = event as {
|
||||
type: string
|
||||
event: {
|
||||
type: string
|
||||
content_block: { type: string }
|
||||
delta: { type: string; text: string }
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
!hasStartedStreaming &&
|
||||
|
||||
@@ -436,7 +436,9 @@ export function evaluateTimeBasedTrigger(
|
||||
return null
|
||||
}
|
||||
const gapMinutes =
|
||||
(Date.now() - new Date(lastAssistant.timestamp as string | number).getTime()) / 60_000
|
||||
(Date.now() -
|
||||
new Date(lastAssistant.timestamp as string | number).getTime()) /
|
||||
60_000
|
||||
if (!Number.isFinite(gapMinutes) || gapMinutes < config.gapThresholdMinutes) {
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -1,22 +1,25 @@
|
||||
// Auto-generated stub — replace with real implementation
|
||||
export {};
|
||||
export {}
|
||||
|
||||
import type { Message } from 'src/types/message';
|
||||
import type { CompactionResult } from './compact.js';
|
||||
import type { Message } from 'src/types/message'
|
||||
import type { CompactionResult } from './compact.js'
|
||||
|
||||
export const isReactiveOnlyMode: () => boolean = () => false;
|
||||
export const isReactiveOnlyMode: () => boolean = () => false
|
||||
export const reactiveCompactOnPromptTooLong: (
|
||||
messages: Message[],
|
||||
cacheSafeParams: Record<string, unknown>,
|
||||
options: { customInstructions?: string; trigger?: string },
|
||||
) => Promise<{ ok: boolean; reason?: string; result?: CompactionResult }> = async () => ({ ok: false });
|
||||
export const isReactiveCompactEnabled: () => boolean = () => false;
|
||||
export const isWithheldPromptTooLong: (message: Message) => boolean = () => false;
|
||||
export const isWithheldMediaSizeError: (message: Message) => boolean = () => false;
|
||||
) => Promise<{ ok: boolean; reason?: string; result?: CompactionResult }> =
|
||||
async () => ({ ok: false })
|
||||
export const isReactiveCompactEnabled: () => boolean = () => false
|
||||
export const isWithheldPromptTooLong: (message: Message) => boolean = () =>
|
||||
false
|
||||
export const isWithheldMediaSizeError: (message: Message) => boolean = () =>
|
||||
false
|
||||
export const tryReactiveCompact: (params: {
|
||||
hasAttempted: boolean;
|
||||
querySource: string;
|
||||
aborted: boolean;
|
||||
messages: Message[];
|
||||
cacheSafeParams: Record<string, unknown>;
|
||||
}) => Promise<CompactionResult | null> = async () => null;
|
||||
hasAttempted: boolean
|
||||
querySource: string
|
||||
aborted: boolean
|
||||
messages: Message[]
|
||||
cacheSafeParams: Record<string, unknown>
|
||||
}) => Promise<CompactionResult | null> = async () => null
|
||||
|
||||
@@ -135,7 +135,9 @@ async function initSessionMemoryCompactConfig(): Promise<void> {
|
||||
export function hasTextBlocks(message: Message): boolean {
|
||||
if (message.type === 'assistant') {
|
||||
const content = message.message!.content
|
||||
return Array.isArray(content) && content.some(block => block.type === 'text')
|
||||
return (
|
||||
Array.isArray(content) && content.some(block => block.type === 'text')
|
||||
)
|
||||
}
|
||||
if (message.type === 'user') {
|
||||
const content = message.message!.content
|
||||
|
||||
@@ -56,5 +56,5 @@ export function projectSnippedView(messages: Message[]): Message[] {
|
||||
return messages
|
||||
}
|
||||
|
||||
return messages.filter((msg) => !removedSet.has(msg.uuid))
|
||||
return messages.filter(msg => !removedSet.has(msg.uuid))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user