Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions packages/cli/src/__tests__/pi-transcript.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,24 @@ function toolStatus(entry: MakaPiToolEntry | undefined): string | undefined {
}

describe('Maka Pi TUI transcript', () => {
test('renders provider dropping guidance from durable declaration state', () => {
const state = createMakaPiTranscriptState();
replaceTranscriptWithStoredMessages(state, [
{
type: 'system_note',
id: 'drop-1',
turnId: 't1',
ts: 1,
kind: 'context_provider_dropping',
data: { inputTokens: 100, priorInputTokens: 100, contextWindowDeclared: true },
},
]);
assert.match(
renderMakaPiTranscript(state, meta(), 120).map(stripAnsi).join('\n'),
/already declared/,
);
});

test('renders manual compaction from the typed terminal outcome', async () => {
for (const [outcome, expected] of [
[{ kind: 'compacted' as const, checkpointId: 'checkpoint-1' }, 'Context compacted.'],
Expand Down
20 changes: 15 additions & 5 deletions packages/cli/src/pi-transcript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1355,14 +1355,24 @@ function systemNoteText(message: SystemNoteMessage): string | undefined {
return 'Context summary failed; the session continued without a new summary.';
case 'context_provider_dropping': {
const data = message.data as
| { inputTokens?: unknown; priorInputTokens?: unknown }
| { inputTokens?: unknown; priorInputTokens?: unknown; contextWindowDeclared?: unknown }
| undefined;
const used = typeof data?.inputTokens === 'number' ? data.inputTokens : undefined;
const prior = typeof data?.priorInputTokens === 'number' ? data.priorInputTokens : undefined;
if (used === undefined || prior === undefined) {
return 'The provider is dropping or rewriting context: content was appended but its reported usage did not grow. Declare a context window for this model so Maka compacts first.';
}
return `The provider is dropping or rewriting context: content was appended, and it counted ${used} input tokens against ${prior} before, which is no growth. Declare a context window for this model so Maka compacts first.`;
const declared =
typeof data?.contextWindowDeclared === 'boolean' ? data.contextWindowDeclared : undefined;
if (used === undefined || prior === undefined)
return declared === true
? 'The provider is dropping or rewriting context, but a context window is already declared for this model; Maka will compact first.'
: declared === false
? 'The provider is dropping or rewriting context: content was appended but its reported usage did not grow. Declare a context window for this model so Maka compacts first.'
: 'The provider is dropping or rewriting context: content was appended but its reported usage did not grow.';
const detail = `The provider is dropping or rewriting context: content was appended, and it counted ${used} input tokens against ${prior} before, which is no growth.`;
return declared === true
? `${detail} A context window is already declared for this model, so Maka will compact first.`
: declared === false
? `${detail} Declare a context window for this model so Maka compacts first.`
: detail;
}
case 'context_overflow_after_compaction':
return 'History was compacted and the provider still called this request too large. What remains also carries the system prompt, the tool schemas, the summary and the recent tail; shortening this message is the part you control.';
Expand Down
20 changes: 17 additions & 3 deletions packages/runtime/src/__tests__/mid-turn-capacity-backend.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1323,7 +1323,11 @@ function defineMidTurnSuite(consumer: ConsumerMode): void {
(message): message is { type: 'system_note'; kind: string; data?: unknown } =>
(message as { kind?: string }).kind === 'context_provider_dropping',
);
assert.deepEqual(note?.data, { inputTokens: 3_716, priorInputTokens: 3_716 });
assert.deepEqual(note?.data, {
inputTokens: 3_716,
priorInputTokens: 3_716,
contextWindowDeclared: false,
});
});

test('does not report dropping across the boundary when the input grew', async () => {
Expand Down Expand Up @@ -1399,10 +1403,15 @@ function defineMidTurnSuite(consumer: ConsumerMode): void {
await runFixtureTurn(fixture, consumer);

const note = fixture.messages.find(
(message): message is { type: 'system_note'; kind: string } =>
(message): message is { type: 'system_note'; kind: string; data?: unknown } =>
(message as { type?: string }).type === 'system_note',
);
assert.equal(note?.kind, 'context_provider_dropping');
assert.deepEqual(note?.data, {
inputTokens: 100,
priorInputTokens: 100,
contextWindowDeclared: true,
});
});

test('records provider context dropping only for an unshaped usage decrease', async () => {
Expand All @@ -1414,10 +1423,15 @@ function defineMidTurnSuite(consumer: ConsumerMode): void {
await runFixtureTurn(fixture, consumer);

const note = fixture.messages.find(
(message): message is { type: 'system_note'; kind: string } =>
(message): message is { type: 'system_note'; kind: string; data?: unknown } =>
(message as { type?: string }).type === 'system_note',
);
assert.equal(note?.kind, 'context_provider_dropping');
assert.deepEqual(note?.data, {
inputTokens: 50,
priorInputTokens: 100,
contextWindowDeclared: true,
});
});

test('does not call provider context dropping when active pruning explains the decrease', async () => {
Expand Down
1 change: 1 addition & 0 deletions packages/runtime/src/ai-sdk-turn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1734,6 +1734,7 @@ export class AiSdkTurn {
await this.recordSystemNote('context_provider_dropping', turnId, {
inputTokens: stepUsage.inputTokens,
priorInputTokens: priorInput,
contextWindowDeclared: midTurnState.capacity !== undefined,
});
}
// Fail closed: reset on every step boundary so a missing final
Expand Down
17 changes: 17 additions & 0 deletions packages/ui/src/__tests__/materialize.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,23 @@ describe("steering timeline", () => {
});

describe("materializeChat message metadata", () => {
test("renders provider dropping guidance from durable declaration state", () => {
const base = {
type: "system_note" as const,
id: "drop",
turnId: "t1",
ts: 1,
kind: "context_provider_dropping" as const,
data: { inputTokens: 98_247, priorInputTokens: 124_832 },
};
const declared = materializeChat([{ ...base, data: { ...base.data, contextWindowDeclared: true } }], "en")[0]?.text;
const undeclared = materializeChat([{ ...base, data: { ...base.data, contextWindowDeclared: false } }], "en")[0]?.text;
const legacy = materializeChat([base], "en")[0]?.text;
assert.match(declared ?? "", /already declared/);
assert.match(undeclared ?? "", /Declare a context window/);
assert.doesNotMatch(legacy ?? "", /Declare a context window/);
});

test("localizes visible system notes", () => {
const messages: StoredMessage[] = [
{
Expand Down
23 changes: 16 additions & 7 deletions packages/ui/src/conversation-copy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ export interface ConversationCopy {
contextCompacting: string;
contextCompacted: string;
contextCompactionFailedOpen: string;
contextProviderDropping: (used: number, prior: number) => string;
contextProviderDropping: (used: number, prior: number, contextWindowDeclared?: boolean) => string;
contextWindowSuggestion: (tokens: number, declared: number | undefined) => string;
contextWindowOverrun: (used: number, declared: number) => string;
contextReportedWindowExceeded: (used: number, reported: number) => string;
Expand Down Expand Up @@ -561,8 +561,11 @@ const CONVERSATION_COPY = {
contextCompacting: '正在压缩上下文…',
contextCompacted: '已压缩较早的上下文。',
contextCompactionFailedOpen: '上下文压缩失败。',
contextProviderDropping: (used, prior) =>
`供应商在丢弃或改写上下文:追加了内容,它报告的输入却是 ${used.toLocaleString('zh-CN')} tokens,与之前的 ${prior.toLocaleString('zh-CN')} 相比没有增长。在连接设置里为该模型声明上下文窗口,让 Maka 先行压缩。`,
contextProviderDropping: (used, prior, declared) => declared === true
? `供应商在丢弃或改写上下文:追加了内容,它报告的输入却是 ${used.toLocaleString('zh-CN')} tokens,与之前的 ${prior.toLocaleString('zh-CN')} 相比没有增长。该模型已声明上下文窗口,Maka 会先行压缩。`
: declared === false
? `供应商在丢弃或改写上下文:追加了内容,它报告的输入却是 ${used.toLocaleString('zh-CN')} tokens,与之前的 ${prior.toLocaleString('zh-CN')} 相比没有增长。在连接设置里为该模型声明上下文窗口,让 Maka 先行压缩。`
: `供应商在丢弃或改写上下文:追加了内容,它报告的输入却是 ${used.toLocaleString('zh-CN')} tokens,与之前的 ${prior.toLocaleString('zh-CN')} 相比没有增长。`,
contextWindowSuggestion: (tokens, declared) =>
declared === undefined
? `供应商拒绝了这次请求。该模型未声明上下文窗口;上次成功的用量约 ${tokens} tokens,可将窗口设为该值让 Maka 先行压缩。`
Expand Down Expand Up @@ -724,8 +727,11 @@ const CONVERSATION_COPY = {
contextCompacting: '正在壓縮上下文…',
contextCompacted: '已壓縮較早的上下文。',
contextCompactionFailedOpen: '上下文壓縮失敗。',
contextProviderDropping: (used, prior) =>
`供應商在丟棄或改寫上下文:追加了內容,它報告的輸入卻是 ${used.toLocaleString('zh-TW')} tokens,與之前的 ${prior.toLocaleString('zh-TW')} 相比沒有成長。在連線設定裡為該模型宣告上下文視窗,讓 Maka 先行壓縮。`,
contextProviderDropping: (used, prior, declared) => declared === true
? `供應商在丟棄或改寫上下文:追加了內容,它報告的輸入卻是 ${used.toLocaleString('zh-TW')} tokens,與之前的 ${prior.toLocaleString('zh-TW')} 相比沒有成長。該模型已宣告上下文視窗,Maka 會先行壓縮。`
: declared === false
? `供應商在丟棄或改寫上下文:追加了內容,它報告的輸入卻是 ${used.toLocaleString('zh-TW')} tokens,與之前的 ${prior.toLocaleString('zh-TW')} 相比沒有成長。在連線設定裡為該模型宣告上下文視窗,讓 Maka 先行壓縮。`
: `供應商在丟棄或改寫上下文:追加了內容,它報告的輸入卻是 ${used.toLocaleString('zh-TW')} tokens,與之前的 ${prior.toLocaleString('zh-TW')} 相比沒有成長。`,
contextWindowSuggestion: (tokens, declared) =>
declared === undefined
? `供應商拒絕了這次請求。該模型未宣告上下文視窗;上次成功的用量約 ${tokens} tokens,可將視窗設為該值讓 Maka 先行壓縮。`
Expand Down Expand Up @@ -913,8 +919,11 @@ const CONVERSATION_COPY = {
contextCompacting: 'Compacting context…',
contextCompacted: 'Earlier context compacted.',
contextCompactionFailedOpen: 'Context compaction failed.',
contextProviderDropping: (used, prior) =>
`The provider is dropping or rewriting context: content was appended, and it counted ${used.toLocaleString('en-US')} input tokens against ${prior.toLocaleString('en-US')} before, which is no growth. Declare a context window for this model in the connection settings so Maka compacts first.`,
contextProviderDropping: (used, prior, declared) => declared === true
? `The provider is dropping or rewriting context: content was appended, and it counted ${used.toLocaleString('en-US')} input tokens against ${prior.toLocaleString('en-US')} before, which is no growth. A context window is already declared for this model, so Maka will compact first.`
: declared === false
? `The provider is dropping or rewriting context: content was appended, and it counted ${used.toLocaleString('en-US')} input tokens against ${prior.toLocaleString('en-US')} before, which is no growth. Declare a context window for this model in the connection settings so Maka compacts first.`
: `The provider is dropping or rewriting context: content was appended, and its reported input usage did not grow.`,
contextWindowSuggestion: (tokens, declared) =>
declared === undefined
? `The provider rejected this request. No context window is declared for this model; the last accepted usage was about ${tokens} tokens — set the window to that value so Maka compacts first.`
Expand Down
5 changes: 3 additions & 2 deletions packages/ui/src/materialize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,11 @@ function systemNoteLabel(kind: string, data: unknown, locale: UiLocale): string
if (kind === "context_compacted") return copy.contextCompacted;
if (kind === "context_compaction_failed_open") return copy.contextCompactionFailedOpen;
if (kind === "context_provider_dropping") {
const dropping = data as { inputTokens?: unknown; priorInputTokens?: unknown } | undefined;
const dropping = data as { inputTokens?: unknown; priorInputTokens?: unknown; contextWindowDeclared?: unknown } | undefined;
const used = typeof dropping?.inputTokens === "number" ? dropping.inputTokens : 0;
const prior = typeof dropping?.priorInputTokens === "number" ? dropping.priorInputTokens : 0;
return copy.contextProviderDropping(used, prior);
const declared = typeof dropping?.contextWindowDeclared === "boolean" ? dropping.contextWindowDeclared : undefined;
return copy.contextProviderDropping(used, prior, declared);
}
if (kind === "context_overflow_after_compaction") return copy.contextOverflowAfterCompaction;
if (kind === "context_reported_window_exceeded") {
Expand Down