/** * PUT /api/accounting/incoming-invoices/config * Persists the NON-SECRET engine knobs (enabled, provider, baseUrl, model, mode, * threshold) per org as an AD_Preference. The API key is never accepted here — * it stays in the server env (AP_OCR_LLM_API_KEY). */ import refreshTokenHelper from '../../../utils/refreshTokenHelper' import errorHandlingHelper from '../../../utils/errorHandlingHelper' import { setInboxConfig } from '../../../utils/inbox/inboxDb' import { getInboxScope, buildInboxCtx } from '../../../utils/inbox/scope' const ALLOWED_PROVIDERS = ['openai', 'anthropic', 'compatible', 'ollama'] const ALLOWED_MODES = ['assisted', 'only'] const handleFunc = async (event: any, authToken: any = null) => { const token = authToken ?? await getTokenHelper(event) const scope = getInboxScope(event) if (!scope.orgId) return { status: 401 } const body = await readBody(event) const clean = { enabled: body?.enabled === true, provider: ALLOWED_PROVIDERS.includes(body?.provider) ? body.provider : 'compatible', baseUrl: typeof body?.baseUrl === 'string' ? body.baseUrl.trim().slice(0, 300) : '', model: typeof body?.model === 'string' ? body.model.trim().slice(0, 120) : '', mode: ALLOWED_MODES.includes(body?.mode) ? body.mode : 'assisted', threshold: Math.min(1, Math.max(0, Number(body?.threshold ?? 0.6))) } await setInboxConfig(buildInboxCtx(event, token), 'llm', clean) return { status: 200, llm: clean } } export default defineEventHandler(async (event) => { try { return await handleFunc(event) } catch (err: any) { try { return await handleFunc(event, await refreshTokenHelper(event)) } catch (error: any) { return errorHandlingHelper(err?.data ?? err, error?.data ?? error) } } })