mirror of
https://github.com/Kaelio/ktx.git
synced 2026-06-10 08:05:14 +02:00
fix: warn on claude-code prompt caching during setup
This commit is contained in:
parent
ea3c606b28
commit
daca268fa8
4 changed files with 87 additions and 11 deletions
28
packages/cli/src/claude-code-prompt-caching.ts
Normal file
28
packages/cli/src/claude-code-prompt-caching.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
import type { KtxProjectLlmConfig } from '@ktx/context/project';
|
||||
|
||||
const CLAUDE_CODE_IGNORED_PROMPT_CACHING_FIELDS = [
|
||||
'systemTtl',
|
||||
'toolsTtl',
|
||||
'historyTtl',
|
||||
'vertexFallbackTo5m',
|
||||
] as const;
|
||||
|
||||
export function ignoredClaudeCodePromptCachingFields(config: KtxProjectLlmConfig): string[] {
|
||||
if (config.provider.backend !== 'claude-code' || !config.promptCaching) {
|
||||
return [];
|
||||
}
|
||||
return CLAUDE_CODE_IGNORED_PROMPT_CACHING_FIELDS.filter((key) => key in config.promptCaching).map(
|
||||
(key) => `llm.promptCaching.${key}`,
|
||||
);
|
||||
}
|
||||
|
||||
export function formatClaudeCodePromptCachingWarning(fields: string[]): string | null {
|
||||
if (fields.length === 0) {
|
||||
return null;
|
||||
}
|
||||
return `claude-code ignores ${fields.join(', ')} because the Claude Agent SDK does not expose KTX prompt-cache TTL, tool, or history markers.`;
|
||||
}
|
||||
|
||||
export function formatClaudeCodePromptCachingFix(): string {
|
||||
return 'Remove those promptCaching fields or use anthropic, vertex, or gateway when those cache knobs are required.';
|
||||
}
|
||||
|
|
@ -209,6 +209,44 @@ describe('setup Anthropic model step', () => {
|
|||
expect(authProbe).toHaveBeenCalledWith(expect.objectContaining({ projectDir: tempDir, model: 'sonnet' }));
|
||||
});
|
||||
|
||||
it('warns during Claude Code setup when existing prompt-caching fields will be ignored', async () => {
|
||||
await writeFile(
|
||||
join(tempDir, 'ktx.yaml'),
|
||||
[
|
||||
'llm:',
|
||||
' provider:',
|
||||
' backend: anthropic',
|
||||
' models:',
|
||||
' default: claude-sonnet-4-6',
|
||||
' promptCaching:',
|
||||
' enabled: true',
|
||||
' systemTtl: 1h',
|
||||
' toolsTtl: 1h',
|
||||
' historyTtl: 5m',
|
||||
'',
|
||||
].join('\n'),
|
||||
'utf-8',
|
||||
);
|
||||
const io = makeIo();
|
||||
|
||||
const result = await runKtxSetupAnthropicModelStep(
|
||||
{
|
||||
projectDir: tempDir,
|
||||
inputMode: 'disabled',
|
||||
llmBackend: 'claude-code',
|
||||
skipLlm: false,
|
||||
},
|
||||
io.io,
|
||||
{
|
||||
claudeCodeAuthProbe: async () => ({ ok: true as const }),
|
||||
},
|
||||
);
|
||||
|
||||
expect(result.status).toBe('ready');
|
||||
expect(io.stderr()).toContain('claude-code ignores llm.promptCaching.systemTtl');
|
||||
expect(io.stderr()).toContain('Claude Agent SDK does not expose KTX prompt-cache TTL, tool, or history markers');
|
||||
});
|
||||
|
||||
it('returns from Anthropic credential Back to provider selection', async () => {
|
||||
const prompts = makePromptAdapter({ selectValues: ['anthropic', 'back', 'back'] });
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@ import {
|
|||
serializeKtxProjectConfig,
|
||||
} from '@ktx/context/project';
|
||||
import { type KtxLlmConfig, type KtxLlmHealthCheckResult, runKtxLlmHealthCheck } from '@ktx/llm';
|
||||
import {
|
||||
formatClaudeCodePromptCachingWarning,
|
||||
ignoredClaudeCodePromptCachingFields,
|
||||
} from './claude-code-prompt-caching.js';
|
||||
import { createClackSpinner, type KtxCliSpinner } from './clack.js';
|
||||
import type { KtxCliIo } from './cli-runtime.js';
|
||||
import { withTextInputNavigation } from './prompt-navigation.js';
|
||||
|
|
@ -946,6 +950,14 @@ export async function runKtxSetupAnthropicModelStep(
|
|||
io.stderr.write(`${health.message}\n`);
|
||||
return { status: 'failed', projectDir: args.projectDir };
|
||||
}
|
||||
const warning = formatClaudeCodePromptCachingWarning(
|
||||
ignoredClaudeCodePromptCachingFields(
|
||||
buildProjectLlmConfig(project.config.llm, { backend: 'claude-code' }, model),
|
||||
),
|
||||
);
|
||||
if (warning) {
|
||||
io.stderr.write(`${warning}\n`);
|
||||
}
|
||||
await persistLlmConfig(args.projectDir, { backend: 'claude-code' }, model);
|
||||
io.stdout.write(`│ LLM ready: yes (${model})\n`);
|
||||
return { status: 'ready', projectDir: args.projectDir };
|
||||
|
|
|
|||
|
|
@ -9,6 +9,11 @@ import type {
|
|||
KtxProjectLlmConfig,
|
||||
} from '@ktx/context/project';
|
||||
import type { PostgresPgssProbeResult } from '@ktx/context/ingest';
|
||||
import {
|
||||
formatClaudeCodePromptCachingFix,
|
||||
formatClaudeCodePromptCachingWarning,
|
||||
ignoredClaudeCodePromptCachingFields,
|
||||
} from './claude-code-prompt-caching.js';
|
||||
import type { DoctorCheck } from './doctor.js';
|
||||
import { KTX_NEXT_STEP_DIRECT_COMMANDS } from './next-steps.js';
|
||||
|
||||
|
|
@ -509,13 +514,6 @@ function buildPipelineStatus(config: KtxProjectConfig): PipelineStatus {
|
|||
};
|
||||
}
|
||||
|
||||
function ignoredClaudeCodePromptCachingFields(config: KtxProjectLlmConfig): string[] {
|
||||
if (config.provider.backend !== 'claude-code' || !config.promptCaching) {
|
||||
return [];
|
||||
}
|
||||
return Object.keys(config.promptCaching).map((key) => `llm.promptCaching.${key}`);
|
||||
}
|
||||
|
||||
function buildStorageStatus(config: KtxProjectConfig): StorageStatus {
|
||||
return {
|
||||
state: config.storage.state,
|
||||
|
|
@ -603,11 +601,11 @@ function buildWarnings(
|
|||
});
|
||||
}
|
||||
|
||||
const ignored = ignoredClaudeCodePromptCachingFields(config.llm);
|
||||
if (ignored.length > 0) {
|
||||
const warning = formatClaudeCodePromptCachingWarning(ignoredClaudeCodePromptCachingFields(config.llm));
|
||||
if (warning) {
|
||||
warnings.push({
|
||||
message: `claude-code ignores ${ignored.join(', ')} because the Claude Agent SDK does not expose KTX prompt-cache TTL, tool, or history markers.`,
|
||||
fix: 'Remove those promptCaching fields or use anthropic, vertex, or gateway when those cache knobs are required.',
|
||||
message: warning,
|
||||
fix: formatClaudeCodePromptCachingFix(),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue