improved a lot of things
This commit is contained in:
@@ -138,7 +138,19 @@
|
|||||||
"Bash(grep -E \"\\\\.d\\\\.ts$\")",
|
"Bash(grep -E \"\\\\.d\\\\.ts$\")",
|
||||||
"Bash(pnpm -w ls @anthropic-ai/sdk)",
|
"Bash(pnpm -w ls @anthropic-ai/sdk)",
|
||||||
"Bash(grep -v \"\\\\.map$\")",
|
"Bash(grep -v \"\\\\.map$\")",
|
||||||
"Bash(perl -pi -e 's/background: '\\\\''#FAFAFA'\\\\''/background: '\\\\''var\\(--page-bg\\)'\\\\''/g' /Users/USER/Desktop/originmain/packages/app/src/app/onboarding/page.tsx /Users/USER/Desktop/originmain/packages/app/src/app/error.tsx)"
|
"Bash(perl -pi -e 's/background: '\\\\''#FAFAFA'\\\\''/background: '\\\\''var\\(--page-bg\\)'\\\\''/g' /Users/USER/Desktop/originmain/packages/app/src/app/onboarding/page.tsx /Users/USER/Desktop/originmain/packages/app/src/app/error.tsx)",
|
||||||
|
"Bash(node -e ' *)",
|
||||||
|
"Bash(python3 -c \"import sys,json; [print\\(m['id']\\) for m in json.load\\(sys.stdin\\).get\\('data',[]\\)]\")",
|
||||||
|
"Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); print\\(json.dumps\\({k:d[k] for k in d if k!='content'}, indent=2\\)\\); print\\('TEXT:', next\\(\\(b['text'] for b in d.get\\('content',[]\\) if b['type']=='text'\\),''\\)[:200]\\)\")",
|
||||||
|
"Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); text=next\\(\\(b['text'] for b in d.get\\('content',[]\\) if b['type']=='text'\\),''\\); print\\('STATUS:', d.get\\('type','ok'\\)\\); print\\('TEXT:', text[:300]\\)\")",
|
||||||
|
"Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); print\\('main:', d.get\\('main'\\)\\); print\\('exports:', json.dumps\\(d.get\\('exports',{}\\), indent=2\\)\\); print\\('scripts:', json.dumps\\(d.get\\('scripts',{}\\), indent=2\\)\\)\")",
|
||||||
|
"Bash(curl -s http://localhost:3000/api/ai/query -X POST -H 'Content-Type: application/json' -d '{\"workspace_id\":\"test\",\"question\":\"test\"}')",
|
||||||
|
"Bash(curl -sv http://localhost:3000/api/ai/query -X POST -H 'Content-Type: application/json' -d '{\"workspace_id\":\"test\",\"question\":\"test\"}')",
|
||||||
|
"Bash(curl -s -w '\\\\nHTTP_STATUS:%{http_code}' http://localhost:3000/api/ai/query -X POST -H 'Content-Type: application/json' -d '{\"workspace_id\":\"test\",\"question\":\"test\"}')",
|
||||||
|
"Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); print\\(json.dumps\\(d.get\\('dependencies',{}\\), indent=2\\)\\)\")",
|
||||||
|
"Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); print\\('version:', d.get\\('version'\\)\\)\")",
|
||||||
|
"Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); print\\('type:', d.get\\('type'\\)\\); print\\('error:', d.get\\('error',{}\\).get\\('message','none'\\)[:200]\\)\")",
|
||||||
|
"Bash(python3 -c \"import sys,json; d=json.load\\(sys.stdin\\); text=next\\(\\(b['text'] for b in d.get\\('content',[]\\) if b['type']=='text'\\),''\\); print\\('STATUS:', d.get\\('type','?'\\)\\); print\\('ERROR:', d.get\\('error',{}\\).get\\('message','none'\\)[:300]\\); print\\('TEXT:', text[:300]\\)\")"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ import Anthropic from '@anthropic-ai/sdk';
|
|||||||
|
|
||||||
// ── Model constants ───────────────────────────────────────────────────────────
|
// ── Model constants ───────────────────────────────────────────────────────────
|
||||||
|
|
||||||
// claude-opus-4-5 is the current stable Opus 4 release.
|
// claude-opus-4-7 uses adaptive thinking (thinking.type = 'adaptive').
|
||||||
// Extended thinking is enabled in gateway.ts with budget_tokens.
|
// It does NOT accept temperature, top_p, or top_k — those are omitted in gateway.ts.
|
||||||
export const MODEL = 'claude-opus-4-5' as const;
|
export const MODEL = 'claude-opus-4-7' as const;
|
||||||
|
|
||||||
// ── Singleton client ──────────────────────────────────────────────────────────
|
// ── Singleton client ──────────────────────────────────────────────────────────
|
||||||
// The client is created once and shared. API key is injected from the server
|
// The client is created once and shared. API key is injected from the server
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export async function answerAgentQuestion(
|
|||||||
|
|
||||||
let parsed: unknown;
|
let parsed: unknown;
|
||||||
try {
|
try {
|
||||||
parsed = JSON.parse(response.text);
|
parsed = JSON.parse(response.text.replace(/^```(?:json)?\s*/i, "").replace(/\s*```\s*$/, "").trim());
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Design agent returned unparseable JSON: ${String(err)}. ` +
|
`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".
|
// 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.
|
// 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;
|
let parsed: unknown;
|
||||||
try {
|
try {
|
||||||
parsed = JSON.parse(response.text);
|
parsed = JSON.parse(rawText);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Artboard query returned unparseable JSON: ${String(err)}. ` +
|
`Artboard query returned unparseable JSON: ${String(err)}. ` +
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ export async function fillCompletionZone(
|
|||||||
});
|
});
|
||||||
|
|
||||||
try {
|
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 };
|
return { proposedTree: parsed.proposedTree as unknown, description: String(parsed.description ?? ''), raw: response };
|
||||||
} catch (parseErr) {
|
} catch (parseErr) {
|
||||||
lastError = new Error(
|
lastError = new Error(
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ export async function generateDriftReport(
|
|||||||
// compliance feature. Throw so the caller can surface the error clearly.
|
// compliance feature. Throw so the caller can surface the error clearly.
|
||||||
let parsed: unknown;
|
let parsed: unknown;
|
||||||
try {
|
try {
|
||||||
parsed = JSON.parse(response.text);
|
parsed = JSON.parse(response.text.replace(/^```(?:json)?\s*/i, "").replace(/\s*```\s*$/, "").trim());
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Drift report returned unparseable JSON: ${String(err)}. ` +
|
`Drift report returned unparseable JSON: ${String(err)}. ` +
|
||||||
|
|||||||
@@ -73,10 +73,8 @@ export interface GatewayRequest {
|
|||||||
messages: Anthropic.Messages.MessageParam[];
|
messages: Anthropic.Messages.MessageParam[];
|
||||||
system?: Anthropic.Messages.TextBlockParam[];
|
system?: Anthropic.Messages.TextBlockParam[];
|
||||||
maxTokens?: number;
|
maxTokens?: number;
|
||||||
// NOTE: temperature is intentionally omitted — extended thinking rejects
|
// NOTE: temperature is intentionally omitted — claude-opus-4-7 with
|
||||||
// temperature, top_p, and top_k with a 400 error.
|
// adaptive 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().
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GatewayResponse {
|
export interface GatewayResponse {
|
||||||
@@ -103,15 +101,10 @@ export class AIGateway {
|
|||||||
let lastError: Error | null = null;
|
let lastError: Error | null = null;
|
||||||
for (let attempt = 0; attempt < this.maxRetries; attempt++) {
|
for (let attempt = 0; attempt < this.maxRetries; attempt++) {
|
||||||
try {
|
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({
|
const response = await this.client.messages.create({
|
||||||
model: MODEL,
|
model: MODEL,
|
||||||
max_tokens: maxTokens,
|
max_tokens: req.maxTokens ?? 4096,
|
||||||
thinking: { type: 'enabled', budget_tokens: budgetTokens },
|
thinking: { type: 'adaptive' },
|
||||||
...(req.system !== undefined ? { system: req.system } : {}),
|
...(req.system !== undefined ? { system: req.system } : {}),
|
||||||
messages: req.messages,
|
messages: req.messages,
|
||||||
});
|
});
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user