Skip to content

Commit 8cc619d

Browse files
committed
feat: add GET /ai/byok-test diagnostic endpoint for custom AI verification
1 parent f2f22d5 commit 8cc619d

1 file changed

Lines changed: 71 additions & 0 deletions

File tree

backend/simpatico-ats.js

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1207,6 +1207,9 @@ route("GET", "/billing/subscription", handleGetSubscription);
12071207
route("POST", "/billing/cancel", handleCancelSubscription);
12081208
route("GET", "/billing/transactions", handleListTransactions);
12091209

1210+
// ── BYOK AI Diagnostics ──
1211+
route("GET", "/ai/byok-test", handleBYOKTest);
1212+
12101213
// ═════════════════════════════════════════════════════════════════════════════════════
12111214
// § 13. MAIN ENTRY POINT
12121215
// ═════════════════════════════════════════════════════════════════════════════════════
@@ -6970,3 +6973,71 @@ async function handleListTransactions(request, env, ctx) {
69706973
const data = await res.json();
69716974
return apiResponse(data);
69726975
}
6976+
6977+
/**
6978+
* GET /ai/byok-test — Diagnostic endpoint to verify BYOK AI configuration.
6979+
* Returns provider info, model, latency, and a sample response.
6980+
*/
6981+
async function handleBYOKTest(request, env, ctx) {
6982+
requireAuth(ctx);
6983+
const tenantId = ctx.tenantId;
6984+
6985+
// 1. Fetch AI config
6986+
const aiConfig = await getCompanyAIConfig(env, tenantId);
6987+
6988+
if (!aiConfig) {
6989+
return apiResponse({
6990+
status: "default",
6991+
message: "No custom AI configured. Using Cloudflare Workers AI (default).",
6992+
provider: "cloudflare",
6993+
model: CF_DEFAULT_MODEL,
6994+
byok_active: false,
6995+
});
6996+
}
6997+
6998+
// 2. Resolve provider details
6999+
const { baseUrl, model } = resolveProviderDefaults(aiConfig);
7000+
7001+
// 3. Send a tiny test prompt
7002+
const testMessages = [
7003+
{ role: "system", content: "You are a helpful assistant. Respond in exactly one sentence." },
7004+
{ role: "user", content: "Say hello and confirm which AI model you are." },
7005+
];
7006+
7007+
const startTime = Date.now();
7008+
try {
7009+
const result = aiConfig.provider === "cloudflare"
7010+
? await env.AI.run(aiConfig.cfModel || CF_DEFAULT_MODEL, { messages: testMessages, max_tokens: 100 })
7011+
: await callExternalLLM(aiConfig, testMessages, 100, false);
7012+
7013+
const latencyMs = Date.now() - startTime;
7014+
const responseText = result?.response || result?.choices?.[0]?.message?.content || "(empty response)";
7015+
7016+
console.log(`[BYOK-TEST] SUCCESS for tenant=${tenantId}: provider=${aiConfig.provider}, model=${model}, latency=${latencyMs}ms`);
7017+
7018+
return apiResponse({
7019+
status: "connected",
7020+
byok_active: true,
7021+
provider: aiConfig.provider,
7022+
model: model || aiConfig.cfModel || "(default)",
7023+
base_url: baseUrl || "(cloudflare native)",
7024+
latency_ms: latencyMs,
7025+
response_snippet: responseText.slice(0, 200),
7026+
message: `Custom AI (${aiConfig.provider}) is working. Response received in ${latencyMs}ms.`,
7027+
});
7028+
} catch (err) {
7029+
const latencyMs = Date.now() - startTime;
7030+
console.error(`[BYOK-TEST] FAILED for tenant=${tenantId}: provider=${aiConfig.provider}, error=${err.message}`);
7031+
7032+
return apiResponse({
7033+
status: "error",
7034+
byok_active: true,
7035+
provider: aiConfig.provider,
7036+
model: model || "(unknown)",
7037+
base_url: baseUrl || "(unknown)",
7038+
latency_ms: latencyMs,
7039+
error: err.message,
7040+
message: `Custom AI (${aiConfig.provider}) failed: ${err.message}`,
7041+
}, HTTP.OK); // Return 200 with error details for diagnostic visibility
7042+
}
7043+
}

0 commit comments

Comments
 (0)