improved a lot of things

This commit is contained in:
SinachPat
2026-04-29 04:22:43 +01:00
parent 050c4ce7fe
commit 8d07d97cdc
8 changed files with 27 additions and 20 deletions
+3 -3
View File
@@ -2,9 +2,9 @@ import Anthropic from '@anthropic-ai/sdk';
// ── Model constants ───────────────────────────────────────────────────────────
// claude-opus-4-5 is the current stable Opus 4 release.
// Extended thinking is enabled in gateway.ts with budget_tokens.
export const MODEL = 'claude-opus-4-5' as const;
// claude-opus-4-7 uses adaptive thinking (thinking.type = 'adaptive').
// It does NOT accept temperature, top_p, or top_k — those are omitted in gateway.ts.
export const MODEL = 'claude-opus-4-7' as const;
// ── Singleton client ──────────────────────────────────────────────────────────
// The client is created once and shared. API key is injected from the server
+1 -1
View File
@@ -40,7 +40,7 @@ export async function answerAgentQuestion(
let parsed: unknown;
try {
parsed = JSON.parse(response.text);
parsed = JSON.parse(response.text.replace(/^```(?:json)?\s*/i, "").replace(/\s*```\s*$/, "").trim());
} catch (err) {
throw new Error(
`Design agent returned unparseable JSON: ${String(err)}. ` +
@@ -38,9 +38,11 @@ export async function queryCrossArtboard(
// Returning empty results on parse failure is indistinguishable from "no match".
// Throw so the UI can show an error rather than a misleading empty state.
// Strip markdown code fences that the model occasionally adds despite instructions.
const rawText = response.text.replace(/^```(?:json)?\s*/i, '').replace(/\s*```\s*$/, '').trim();
let parsed: unknown;
try {
parsed = JSON.parse(response.text);
parsed = JSON.parse(rawText);
} catch (err) {
throw new Error(
`Artboard query returned unparseable JSON: ${String(err)}. ` +
@@ -60,7 +60,7 @@ export async function fillCompletionZone(
});
try {
const parsed = JSON.parse(response.text);
const parsed = JSON.parse(response.text.replace(/^```(?:json)?\s*/i, "").replace(/\s*```\s*$/, "").trim());
return { proposedTree: parsed.proposedTree as unknown, description: String(parsed.description ?? ''), raw: response };
} catch (parseErr) {
lastError = new Error(
@@ -70,7 +70,7 @@ export async function generateDriftReport(
// compliance feature. Throw so the caller can surface the error clearly.
let parsed: unknown;
try {
parsed = JSON.parse(response.text);
parsed = JSON.parse(response.text.replace(/^```(?:json)?\s*/i, "").replace(/\s*```\s*$/, "").trim());
} catch (err) {
throw new Error(
`Drift report returned unparseable JSON: ${String(err)}. ` +
+4 -11
View File
@@ -73,10 +73,8 @@ export interface GatewayRequest {
messages: Anthropic.Messages.MessageParam[];
system?: Anthropic.Messages.TextBlockParam[];
maxTokens?: number;
// NOTE: temperature is intentionally omitted — extended thinking rejects
// temperature, top_p, and top_k with a 400 error.
// NOTE: when thinking is enabled, max_tokens must be >= 16_000 and
// budget_tokens must be < max_tokens. We enforce this in complete().
// NOTE: temperature is intentionally omitted — claude-opus-4-7 with
// adaptive thinking rejects temperature, top_p, and top_k with a 400 error.
}
export interface GatewayResponse {
@@ -103,15 +101,10 @@ export class AIGateway {
let lastError: Error | null = null;
for (let attempt = 0; attempt < this.maxRetries; attempt++) {
try {
// Extended thinking requires max_tokens >= 16_000.
// budget_tokens must be strictly less than max_tokens.
const maxTokens = Math.max(req.maxTokens ?? 4096, 16_000);
const budgetTokens = Math.floor(maxTokens * 0.8);
const response = await this.client.messages.create({
model: MODEL,
max_tokens: maxTokens,
thinking: { type: 'enabled', budget_tokens: budgetTokens },
max_tokens: req.maxTokens ?? 4096,
thinking: { type: 'adaptive' },
...(req.system !== undefined ? { system: req.system } : {}),
messages: req.messages,
});
File diff suppressed because one or more lines are too long