mirror of
https://github.com/Kaelio/ktx.git
synced 2026-06-07 07:55:13 +02:00
feat: recognize claude-code llm backend
This commit is contained in:
parent
cb16f8a61c
commit
4af3a6f20b
8 changed files with 199 additions and 12 deletions
|
|
@ -129,6 +129,7 @@
|
|||
"type-check": "tsc -p tsconfig.json --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@anthropic-ai/claude-agent-sdk": "0.3.142",
|
||||
"@ktx/llm": "workspace:*",
|
||||
"@looker/sdk": "^26.8.0",
|
||||
"@looker/sdk-node": "^26.8.0",
|
||||
|
|
|
|||
|
|
@ -180,6 +180,31 @@ llm:
|
|||
});
|
||||
});
|
||||
|
||||
it('parses Claude Code as a first-class LLM backend', () => {
|
||||
const config = parseKtxProjectConfig(`
|
||||
llm:
|
||||
provider:
|
||||
backend: claude-code
|
||||
models:
|
||||
default: sonnet
|
||||
triage: haiku
|
||||
candidateExtraction: sonnet
|
||||
curator: sonnet
|
||||
reconcile: sonnet
|
||||
repair: opus
|
||||
`);
|
||||
|
||||
expect(config.llm.provider.backend).toBe('claude-code');
|
||||
expect(config.llm.models).toEqual({
|
||||
default: 'sonnet',
|
||||
triage: 'haiku',
|
||||
candidateExtraction: 'sonnet',
|
||||
curator: 'sonnet',
|
||||
reconcile: 'sonnet',
|
||||
repair: 'opus',
|
||||
});
|
||||
});
|
||||
|
||||
it('parses gateway LLM, OpenAI scan embeddings, and sentence-transformers ingest embeddings', () => {
|
||||
const config = parseKtxProjectConfig(`
|
||||
llm:
|
||||
|
|
@ -497,7 +522,7 @@ describe('generateKtxProjectConfigJsonSchema', () => {
|
|||
const llm = (schema.properties as Record<string, { properties?: Record<string, unknown> }>).llm;
|
||||
const provider = llm?.properties?.provider as { properties?: Record<string, unknown> };
|
||||
const backend = provider?.properties?.backend as { enum?: readonly string[] };
|
||||
expect(backend?.enum).toEqual(['none', 'anthropic', 'vertex', 'gateway']);
|
||||
expect(backend?.enum).toEqual(['none', 'anthropic', 'vertex', 'gateway', 'claude-code']);
|
||||
|
||||
const storage = (schema.properties as Record<string, { properties?: Record<string, unknown> }>).storage;
|
||||
const state = storage?.properties?.state as { enum?: readonly string[] };
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import YAML from 'yaml';
|
|||
import * as z from 'zod';
|
||||
import { connectionConfigSchema } from './driver-schemas.js';
|
||||
|
||||
const KTX_LLM_BACKENDS = ['none', 'anthropic', 'vertex', 'gateway'] as const;
|
||||
const KTX_LLM_BACKENDS = ['none', 'anthropic', 'vertex', 'gateway', 'claude-code'] as const;
|
||||
const KTX_EMBEDDING_BACKENDS = ['none', 'deterministic', 'openai', 'sentence-transformers'] as const;
|
||||
const KTX_PROMPT_CACHE_TTLS = ['5m', '1h'] as const;
|
||||
const KTX_ENRICHMENT_MODES = ['none', 'deterministic', 'llm'] as const;
|
||||
|
|
@ -46,7 +46,9 @@ const llmProviderSchema = z
|
|||
backend: z
|
||||
.enum(KTX_LLM_BACKENDS)
|
||||
.default('none')
|
||||
.describe('LLM provider backend. "none" disables LLM features; "anthropic" / "vertex" / "gateway" require the matching nested credentials block.'),
|
||||
.describe(
|
||||
'LLM provider backend. "none" disables LLM features; "anthropic" / "vertex" / "gateway" require the matching nested credentials block; "claude-code" uses the local Claude Code session.',
|
||||
),
|
||||
vertex: vertexProviderSchema.optional().describe('Vertex AI credentials, used when backend is "vertex".'),
|
||||
anthropic: apiCredentialsSchema.optional().describe('Anthropic API credentials, used when backend is "anthropic".'),
|
||||
gateway: apiCredentialsSchema.optional().describe('AI Gateway credentials, used when backend is "gateway".'),
|
||||
|
|
|
|||
|
|
@ -61,4 +61,17 @@ describe('KTX LLM health check', () => {
|
|||
message: '401 invalid x-api-key [redacted]',
|
||||
});
|
||||
});
|
||||
|
||||
it('reports claude-code as unsupported by the AI SDK health check', async () => {
|
||||
const result = await runKtxLlmHealthCheck({
|
||||
backend: 'claude-code',
|
||||
modelSlots: { default: 'sonnet' },
|
||||
promptCaching: { enabled: false },
|
||||
});
|
||||
|
||||
expect(result).toEqual({
|
||||
ok: false,
|
||||
message: expect.stringContaining('claude-code is not an AI SDK LanguageModel backend'),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -302,4 +302,14 @@ describe('createKtxLlmProvider', () => {
|
|||
expect(provider.promptCachingConfig().enabled).toBe(false);
|
||||
expect(provider.cacheMarker('1h', 'claude-sonnet-4-6')).toBeUndefined();
|
||||
});
|
||||
|
||||
it('throws instead of falling through when an unsupported LLM backend is passed to the AI SDK provider factory', () => {
|
||||
expect(() =>
|
||||
createKtxLlmProvider({
|
||||
backend: 'claude-code',
|
||||
modelSlots: { default: 'sonnet' },
|
||||
promptCaching: { enabled: false },
|
||||
}),
|
||||
).toThrow('claude-code is not an AI SDK LanguageModel backend');
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -175,14 +175,18 @@ class DefaultKtxLlmProvider implements KtxLlmProvider {
|
|||
return (modelId) => vertex(modelId);
|
||||
}
|
||||
|
||||
const gateway = (deps.createGateway ?? createGateway)({
|
||||
...(config.gateway?.apiKey ? { apiKey: config.gateway.apiKey } : {}),
|
||||
...(config.gateway?.baseURL ? { baseURL: config.gateway.baseURL } : {}),
|
||||
headers: {
|
||||
'anthropic-beta': ANTHROPIC_BETA_HEADER,
|
||||
},
|
||||
});
|
||||
return (modelId) => gateway(modelId);
|
||||
if (config.backend === 'gateway') {
|
||||
const gateway = (deps.createGateway ?? createGateway)({
|
||||
...(config.gateway?.apiKey ? { apiKey: config.gateway.apiKey } : {}),
|
||||
...(config.gateway?.baseURL ? { baseURL: config.gateway.baseURL } : {}),
|
||||
headers: {
|
||||
'anthropic-beta': ANTHROPIC_BETA_HEADER,
|
||||
},
|
||||
});
|
||||
return (modelId) => gateway(modelId);
|
||||
}
|
||||
|
||||
throw new Error(`${config.backend} is not an AI SDK LanguageModel backend; use KtxLlmRuntimePort`);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { LanguageModel, TelemetrySettings, ToolCallRepairFunction, ToolSet
|
|||
export const KTX_MODEL_ROLES = ['default', 'triage', 'candidateExtraction', 'curator', 'reconcile', 'repair'] as const;
|
||||
|
||||
export type KtxModelRole = (typeof KTX_MODEL_ROLES)[number];
|
||||
export type KtxLlmBackend = 'anthropic' | 'vertex' | 'gateway';
|
||||
export type KtxLlmBackend = 'anthropic' | 'vertex' | 'gateway' | 'claude-code';
|
||||
export type KtxPromptCacheTtl = '5m' | '1h';
|
||||
|
||||
export type KtxJsonValue =
|
||||
|
|
|
|||
132
pnpm-lock.yaml
generated
132
pnpm-lock.yaml
generated
|
|
@ -312,6 +312,9 @@ importers:
|
|||
|
||||
packages/context:
|
||||
dependencies:
|
||||
'@anthropic-ai/claude-agent-sdk':
|
||||
specifier: 0.3.142
|
||||
version: 0.3.142(zod@4.4.3)
|
||||
'@ktx/llm':
|
||||
specifier: workspace:*
|
||||
version: link:../llm
|
||||
|
|
@ -475,6 +478,65 @@ packages:
|
|||
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
'@anthropic-ai/claude-agent-sdk-darwin-arm64@0.3.142':
|
||||
resolution: {integrity: sha512-yBHOiRqJ8JcD9OAMGJALbypaD3u3K8hyUmcnZ+91AHJtymzWxuMkVi4IY1qp8L5jzkKeTnvYfCspzkbiHLuYWg==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@anthropic-ai/claude-agent-sdk-darwin-x64@0.3.142':
|
||||
resolution: {integrity: sha512-/a/bVMjvAl3gNzWiPIgynYktTYckTcp4YAacV/2F4Jd8XeCV0+DMQW7OFeR+3fnPcBg/8kcOAVYfLZXDExqO1w==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@anthropic-ai/claude-agent-sdk-linux-arm64-musl@0.3.142':
|
||||
resolution: {integrity: sha512-KZuwSupNJovnMJ7MZxjp1Qq0yu7rAmbzO4Zlmr3jtKDU95t2kgs3c6j4evzQDCgTQMlwH8QTSV4mItDGxlYEbg==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@anthropic-ai/claude-agent-sdk-linux-arm64@0.3.142':
|
||||
resolution: {integrity: sha512-QKG553PSbIcQ5KLvnl2ekfy5lTyU3dW/X5fDQlRLv4YHNHnqf2o7scJ6eUdfaVTQdIZ+Pa7SNN3bsvVs4bNjQw==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@anthropic-ai/claude-agent-sdk-linux-x64-musl@0.3.142':
|
||||
resolution: {integrity: sha512-QkDwLMsdYO7n/i1zPCt5YZIet5u+Eo07UpF9UX5yD7bnwRZKDe22L6LVVwiLLjeTO0fTz+uNY7w9/XOYQMlxUQ==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@anthropic-ai/claude-agent-sdk-linux-x64@0.3.142':
|
||||
resolution: {integrity: sha512-o1QZmCNRL5BFTc14KEvT23Fxm1jNv0aa0e9T0OZUjua0oW8DRpri3HKvDEM36qEGWUOANBG7h6Ca/KNqxaTnYg==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@anthropic-ai/claude-agent-sdk-win32-arm64@0.3.142':
|
||||
resolution: {integrity: sha512-x8lbY1m7E/BiFF0Gu/Mx9lkD/zW3vBr3viw0GYNuqY9GYHfLOX9+l9H8C+INeGzB4+ibG8+xD2pnRhWdQxuvUg==}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@anthropic-ai/claude-agent-sdk-win32-x64@0.3.142':
|
||||
resolution: {integrity: sha512-NpNxdiCEUNjjwvBltpDnkgdjVQ+nRsALpfM1Pe4GhnYiOkTk/TvjMZUuA2qGh0F8KyF0FbqzUsi0uXIgojJT5w==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@anthropic-ai/claude-agent-sdk@0.3.142':
|
||||
resolution: {integrity: sha512-k1xBon6ov0PT/vZNf+Z+SuAqmylGJU/+a+h/k04MW5cBbzOIwiVcGFRTGJ/qbY5pcboJbLtts/yBwSu9AvSipg==}
|
||||
engines: {node: '>=18.0.0'}
|
||||
peerDependencies:
|
||||
zod: ^4.0.0
|
||||
|
||||
'@anthropic-ai/sdk@0.93.0':
|
||||
resolution: {integrity: sha512-q9vaSZQVFx6B/gPxetGYfLXSJD5v0sOmh0OpZDq7yCrTSA+Rscvrtyol7JJTW40wEpQB4U1B4JXzxQitbQ3CAA==}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
zod: ^3.25.0 || ^4.0.0
|
||||
peerDependenciesMeta:
|
||||
zod:
|
||||
optional: true
|
||||
|
||||
'@aws-crypto/crc32@5.2.0':
|
||||
resolution: {integrity: sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==}
|
||||
engines: {node: '>=16.0.0'}
|
||||
|
|
@ -799,6 +861,10 @@ packages:
|
|||
engines: {node: '>=6.0.0'}
|
||||
hasBin: true
|
||||
|
||||
'@babel/runtime@7.29.2':
|
||||
resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
'@babel/types@7.29.0':
|
||||
resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
|
@ -3656,6 +3722,10 @@ packages:
|
|||
json-bigint@1.0.0:
|
||||
resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==}
|
||||
|
||||
json-schema-to-ts@3.1.1:
|
||||
resolution: {integrity: sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==}
|
||||
engines: {node: '>=16'}
|
||||
|
||||
json-schema-traverse@1.0.0:
|
||||
resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
|
||||
|
||||
|
|
@ -4752,6 +4822,9 @@ packages:
|
|||
trough@2.2.0:
|
||||
resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==}
|
||||
|
||||
ts-algebra@2.0.0:
|
||||
resolution: {integrity: sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==}
|
||||
|
||||
tslib@2.8.1:
|
||||
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
|
||||
|
||||
|
|
@ -5080,6 +5153,54 @@ snapshots:
|
|||
|
||||
'@alloc/quick-lru@5.2.0': {}
|
||||
|
||||
'@anthropic-ai/claude-agent-sdk-darwin-arm64@0.3.142':
|
||||
optional: true
|
||||
|
||||
'@anthropic-ai/claude-agent-sdk-darwin-x64@0.3.142':
|
||||
optional: true
|
||||
|
||||
'@anthropic-ai/claude-agent-sdk-linux-arm64-musl@0.3.142':
|
||||
optional: true
|
||||
|
||||
'@anthropic-ai/claude-agent-sdk-linux-arm64@0.3.142':
|
||||
optional: true
|
||||
|
||||
'@anthropic-ai/claude-agent-sdk-linux-x64-musl@0.3.142':
|
||||
optional: true
|
||||
|
||||
'@anthropic-ai/claude-agent-sdk-linux-x64@0.3.142':
|
||||
optional: true
|
||||
|
||||
'@anthropic-ai/claude-agent-sdk-win32-arm64@0.3.142':
|
||||
optional: true
|
||||
|
||||
'@anthropic-ai/claude-agent-sdk-win32-x64@0.3.142':
|
||||
optional: true
|
||||
|
||||
'@anthropic-ai/claude-agent-sdk@0.3.142(zod@4.4.3)':
|
||||
dependencies:
|
||||
'@anthropic-ai/sdk': 0.93.0(zod@4.4.3)
|
||||
'@modelcontextprotocol/sdk': 1.29.0(zod@4.4.3)
|
||||
zod: 4.4.3
|
||||
optionalDependencies:
|
||||
'@anthropic-ai/claude-agent-sdk-darwin-arm64': 0.3.142
|
||||
'@anthropic-ai/claude-agent-sdk-darwin-x64': 0.3.142
|
||||
'@anthropic-ai/claude-agent-sdk-linux-arm64': 0.3.142
|
||||
'@anthropic-ai/claude-agent-sdk-linux-arm64-musl': 0.3.142
|
||||
'@anthropic-ai/claude-agent-sdk-linux-x64': 0.3.142
|
||||
'@anthropic-ai/claude-agent-sdk-linux-x64-musl': 0.3.142
|
||||
'@anthropic-ai/claude-agent-sdk-win32-arm64': 0.3.142
|
||||
'@anthropic-ai/claude-agent-sdk-win32-x64': 0.3.142
|
||||
transitivePeerDependencies:
|
||||
- '@cfworker/json-schema'
|
||||
- supports-color
|
||||
|
||||
'@anthropic-ai/sdk@0.93.0(zod@4.4.3)':
|
||||
dependencies:
|
||||
json-schema-to-ts: 3.1.1
|
||||
optionalDependencies:
|
||||
zod: 4.4.3
|
||||
|
||||
'@aws-crypto/crc32@5.2.0':
|
||||
dependencies:
|
||||
'@aws-crypto/util': 5.2.0
|
||||
|
|
@ -6002,6 +6123,8 @@ snapshots:
|
|||
dependencies:
|
||||
'@babel/types': 7.29.0
|
||||
|
||||
'@babel/runtime@7.29.2': {}
|
||||
|
||||
'@babel/types@7.29.0':
|
||||
dependencies:
|
||||
'@babel/helper-string-parser': 7.27.1
|
||||
|
|
@ -6443,6 +6566,7 @@ snapshots:
|
|||
|
||||
'@ktx/context@file:packages/context(js-yaml@4.1.1)':
|
||||
dependencies:
|
||||
'@anthropic-ai/claude-agent-sdk': 0.3.142(zod@4.4.3)
|
||||
'@ktx/llm': file:packages/llm(zod@4.4.3)
|
||||
'@looker/sdk': 26.8.0
|
||||
'@looker/sdk-node': 26.8.0
|
||||
|
|
@ -6468,6 +6592,7 @@ snapshots:
|
|||
|
||||
'@ktx/context@file:packages/context(js-yaml@4.1.1)(ws@8.20.0)':
|
||||
dependencies:
|
||||
'@anthropic-ai/claude-agent-sdk': 0.3.142(zod@4.4.3)
|
||||
'@ktx/llm': file:packages/llm(ws@8.20.0)(zod@4.4.3)
|
||||
'@looker/sdk': 26.8.0
|
||||
'@looker/sdk-node': 26.8.0
|
||||
|
|
@ -8884,6 +9009,11 @@ snapshots:
|
|||
dependencies:
|
||||
bignumber.js: 9.3.1
|
||||
|
||||
json-schema-to-ts@3.1.1:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.29.2
|
||||
ts-algebra: 2.0.0
|
||||
|
||||
json-schema-traverse@1.0.0: {}
|
||||
|
||||
json-schema-typed@8.0.2: {}
|
||||
|
|
@ -10439,6 +10569,8 @@ snapshots:
|
|||
|
||||
trough@2.2.0: {}
|
||||
|
||||
ts-algebra@2.0.0: {}
|
||||
|
||||
tslib@2.8.1: {}
|
||||
|
||||
tunnel-agent@0.6.0:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue