From 83d09dfc87c3cc7b44e07b73a4cc8490b90bc5d9 Mon Sep 17 00:00:00 2001 From: Harlan Wilton Date: Sat, 10 Oct 2026 17:22:53 +1100 Subject: [PATCH 1/3] chore(ai): use Claude 5.5 models throughout --- layers/identity/server/tasks/send-digests.ts | 2 +- layers/identity/server/utils/digest-summary.ts | 7 ++++--- layers/registry/server/jobs/generate-faqs.ts | 2 +- layers/registry/server/jobs/generate-summary.ts | 2 +- layers/registry/server/jobs/generate-tags.ts | 2 +- layers/registry/server/tasks/ai-generate-submit.ts | 3 ++- shared/server/anthropic.ts | 7 ++++--- workers/skill-harness/src/gateway.ts | 5 +++-- workers/skill-harness/test/gateway.test.ts | 9 +++++---- 9 files changed, 22 insertions(+), 17 deletions(-) diff --git a/layers/identity/server/tasks/send-digests.ts b/layers/identity/server/tasks/send-digests.ts index 8676f99d..b194fc56 100644 --- a/layers/identity/server/tasks/send-digests.ts +++ b/layers/identity/server/tasks/send-digests.ts @@ -17,7 +17,7 @@ import { renderDigest } from '../utils/digest-template' import { sendEmailWithEnv, signUnsubToken } from '../utils/email' const CRON = '0 9 1 * *' -// Kill switch: the per-repo digest sentence runs `anthropic/claude-haiku-4.5`, +// Kill switch: the per-repo digest sentence runs `anthropic/claude-haiku-5.5`, // a partner model brokered through the Workers AI binding, so every call bills // against AI Gateway credits. Those credits are exhausted, so each monthly run // returned `provider_failure: 2021: Insufficient AI Gateway credits`, delivered diff --git a/layers/identity/server/utils/digest-summary.ts b/layers/identity/server/utils/digest-summary.ts index 49c0efec..f6827b89 100644 --- a/layers/identity/server/utils/digest-summary.ts +++ b/layers/identity/server/utils/digest-summary.ts @@ -15,15 +15,15 @@ export interface AiBinding { messages: Array<{ role: 'user' | 'assistant', content: string }> max_tokens: number system?: string - temperature?: number + thinking?: { type: 'disabled' } }) => Promise } -// Anthropic Haiku 4.5 brokered through Workers AI. The binding handles auth; +// Anthropic Haiku 5.5 brokered through Workers AI. The binding handles auth; // no Anthropic key or gateway token needed. Swap to a llama/qwen if cost or // latency need to drop later — caller doesn't care which model produced // `response`. -const MODEL = 'anthropic/claude-haiku-4.5' +const MODEL = 'anthropic/claude-haiku-5.5' export interface SubscriptionContext { owner: string @@ -133,6 +133,7 @@ Output JSON only, no prose, with this exact shape: system: systemPrompt, messages: [{ role: 'user', content: userPrompt }], max_tokens: 1024, + thinking: { type: 'disabled' }, }).then( value => ({ _tag: 'response' as const, value }), error => ({ diff --git a/layers/registry/server/jobs/generate-faqs.ts b/layers/registry/server/jobs/generate-faqs.ts index bf43dc8e..00472a8d 100644 --- a/layers/registry/server/jobs/generate-faqs.ts +++ b/layers/registry/server/jobs/generate-faqs.ts @@ -73,7 +73,7 @@ export async function generateFaqs(ctx: FaqContext, skill: FaqSkill): Promise { - const { systemPrompt, userPrompt, model = 'claude-haiku-4-5-20251001' } = opts + const { systemPrompt, userPrompt, model = 'claude-haiku-5-5' } = opts // CC wraps/injects its own framing around --system-prompt, so Haiku tends // to stay conversational. For batch jobs we fold the system prompt into the diff --git a/workers/skill-harness/src/gateway.ts b/workers/skill-harness/src/gateway.ts index e29860af..9f7ea45d 100644 --- a/workers/skill-harness/src/gateway.ts +++ b/workers/skill-harness/src/gateway.ts @@ -90,9 +90,10 @@ export async function forwardSandboxRequest( if (!await options.consumeModelCall()) return Response.json({ code: 'MODEL_CALL_LIMIT' }, { status: 403 }) const standardInput = { ...input } - delete standardInput.speed + for (const field of ['speed', 'temperature', 'top_p', 'top_k']) + delete standardInput[field] const thinking = input.thinking && typeof input.thinking === 'object' && 'type' in input.thinking && input.thinking.type === 'enabled' - ? { type: 'enabled', budget_tokens: 2048 } + ? { type: 'adaptive' } : input.thinking return fetchClient('https://api.anthropic.com/v1/messages', { method: 'POST', diff --git a/workers/skill-harness/test/gateway.test.ts b/workers/skill-harness/test/gateway.test.ts index f898316d..31fa6258 100644 --- a/workers/skill-harness/test/gateway.test.ts +++ b/workers/skill-harness/test/gateway.test.ts @@ -132,18 +132,19 @@ describe('sandbox credential gateway', () => { }) it('routes Anthropic with Worker credentials and enforced model limits', async () => { - const options = { ...fixture(), provider: 'anthropic' as const, model: 'claude-sonnet-4-6' } + const options = { ...fixture(), provider: 'anthropic' as const, model: 'claude-sonnet-5-5' } const response = await forwardSandboxRequest(new Request('https://api.anthropic.com/v1/messages', { method: 'POST', headers: { 'x-api-key': 'container-key', 'anthropic-beta': 'untrusted-beta' }, - body: JSON.stringify({ model: 'expensive-model', max_tokens: 32000, service_tier: 'priority', speed: 'fast', messages: [], thinking: { type: 'enabled', budget_tokens: 16000 } }), + body: JSON.stringify({ model: 'expensive-model', max_tokens: 32000, service_tier: 'priority', speed: 'fast', temperature: 0.3, top_p: 0.9, top_k: 20, messages: [], thinking: { type: 'enabled', budget_tokens: 16000 } }), }), options) expect(response.status).toBe(200) const [, forwarded] = options.fetch.mock.calls[0]! expect(new Headers(forwarded?.headers).get('x-api-key')).toBe('worker-only-secret') expect(new Headers(forwarded?.headers).get('anthropic-beta')).toBeNull() - expect(JSON.parse(String(forwarded?.body))).not.toHaveProperty('speed') - expect(JSON.parse(String(forwarded?.body))).toMatchObject({ model: 'claude-sonnet-4-6', max_tokens: 8192, service_tier: 'standard_only', thinking: { type: 'enabled', budget_tokens: 2048 } }) + for (const field of ['speed', 'temperature', 'top_p', 'top_k']) + expect(JSON.parse(String(forwarded?.body))).not.toHaveProperty(field) + expect(JSON.parse(String(forwarded?.body))).toMatchObject({ model: 'claude-sonnet-5-5', max_tokens: 8192, service_tier: 'standard_only', thinking: { type: 'adaptive' } }) }) it.each([{ tools: [{ type: 'web_search_20250305' }] }, { mcp_servers: [{ url: 'https://external.example' }] }])('blocks Anthropic hosted execution %j', async (body) => { From 86a3e1b06e06b3b8fa51199b3448fe70cc9115d0 Mon Sep 17 00:00:00 2001 From: Harlan Wilton Date: Sat, 10 Oct 2026 17:28:18 +1100 Subject: [PATCH 2/3] fix(ai): use supported Sonnet 5.5 on Workers AI --- layers/identity/server/tasks/send-digests.ts | 2 +- layers/identity/server/utils/digest-summary.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/layers/identity/server/tasks/send-digests.ts b/layers/identity/server/tasks/send-digests.ts index b194fc56..f972d9a5 100644 --- a/layers/identity/server/tasks/send-digests.ts +++ b/layers/identity/server/tasks/send-digests.ts @@ -17,7 +17,7 @@ import { renderDigest } from '../utils/digest-template' import { sendEmailWithEnv, signUnsubToken } from '../utils/email' const CRON = '0 9 1 * *' -// Kill switch: the per-repo digest sentence runs `anthropic/claude-haiku-5.5`, +// Kill switch: the per-repo digest sentence runs `anthropic/claude-sonnet-5.5`, // a partner model brokered through the Workers AI binding, so every call bills // against AI Gateway credits. Those credits are exhausted, so each monthly run // returned `provider_failure: 2021: Insufficient AI Gateway credits`, delivered diff --git a/layers/identity/server/utils/digest-summary.ts b/layers/identity/server/utils/digest-summary.ts index f6827b89..fd138b01 100644 --- a/layers/identity/server/utils/digest-summary.ts +++ b/layers/identity/server/utils/digest-summary.ts @@ -15,15 +15,15 @@ export interface AiBinding { messages: Array<{ role: 'user' | 'assistant', content: string }> max_tokens: number system?: string - thinking?: { type: 'disabled' } + thinking?: { type: 'between_tools' } }) => Promise } -// Anthropic Haiku 5.5 brokered through Workers AI. The binding handles auth; +// Anthropic Sonnet 5.5 brokered through Workers AI. The binding handles auth; // no Anthropic key or gateway token needed. Swap to a llama/qwen if cost or // latency need to drop later — caller doesn't care which model produced // `response`. -const MODEL = 'anthropic/claude-haiku-5.5' +const MODEL = 'anthropic/claude-sonnet-5.5' export interface SubscriptionContext { owner: string @@ -133,7 +133,7 @@ Output JSON only, no prose, with this exact shape: system: systemPrompt, messages: [{ role: 'user', content: userPrompt }], max_tokens: 1024, - thinking: { type: 'disabled' }, + thinking: { type: 'between_tools' }, }).then( value => ({ _tag: 'response' as const, value }), error => ({ From 8fbf5eaa3b17b7f8956e14150d990a3e7521b65d Mon Sep 17 00:00:00 2001 From: Harlan Wilton Date: Sat, 10 Oct 2026 17:33:16 +1100 Subject: [PATCH 3/3] fix(ai): align batch estimates with Haiku 5.5 pricing --- layers/registry/server/tasks/ai-generate-poll.ts | 6 +++--- layers/registry/server/utils/ai-prompts.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/layers/registry/server/tasks/ai-generate-poll.ts b/layers/registry/server/tasks/ai-generate-poll.ts index 5ae84910..65d5f255 100644 --- a/layers/registry/server/tasks/ai-generate-poll.ts +++ b/layers/registry/server/tasks/ai-generate-poll.ts @@ -39,9 +39,9 @@ interface BatchResultLine { } } -// Haiku 4.5 batch pricing per million tokens (50% discount off realtime). -const HAIKU_BATCH_INPUT_USD_PER_MTOK = 0.50 -const HAIKU_BATCH_OUTPUT_USD_PER_MTOK = 2.50 +// Haiku 5.5 batch pricing per million tokens for prompts under 100k tokens. +const HAIKU_BATCH_INPUT_USD_PER_MTOK = 0.05 +const HAIKU_BATCH_OUTPUT_USD_PER_MTOK = 0.25 interface BatchStatusResponse { id: string diff --git a/layers/registry/server/utils/ai-prompts.ts b/layers/registry/server/utils/ai-prompts.ts index 39c0a514..8fdd24a2 100644 --- a/layers/registry/server/utils/ai-prompts.ts +++ b/layers/registry/server/utils/ai-prompts.ts @@ -3,7 +3,7 @@ * Anthropic's prompt caching (5-min ephemeral TTL) materially cuts cost when * a batch submits dozens of skills in one request. * - * Three derivation kinds run through Haiku 4.5 Batch API: + * Three derivation kinds run through Haiku 5.5 Batch API: * - `summary` plain text, 2-3 sentences * - `tags` JSON array of 5-10 lowercase tags * - `faq` JSON array of 3-5 { question, answer } objects