u
This commit is contained in:
@@ -4609,7 +4609,7 @@
|
|||||||
"Delivery"
|
"Delivery"
|
||||||
],
|
],
|
||||||
"summary": "Parse document (SSE)",
|
"summary": "Parse document (SSE)",
|
||||||
"description": "Accepts an invoice or delivery note as PDF or text file\n(`multipart/form-data`, field `file`) and streams extraction results as\nServer-Sent Events until parsing is complete.\n\nPDFs are read via `pdftotext -layout`; text files are decoded as UTF-8.\nPages are separated by the form feed character (`\\f`). If no form feed\nis present, the input is treated as a single page.\n\nThe extracted pages are fed to an LLM (OpenRouter) which fills a structured\nmanifest of header data and line items. The OpenRouter API key is read from\nthe authenticated user's company setting `keys.openrouter`; the endpoint\nreturns `400` if the key is not configured.\n\nThe stream ends after the final `result` event (or an `error` event on failure).\n",
|
"description": "Accepts an invoice or delivery note as PDF or text file\n(`multipart/form-data`, field `file`) and streams extraction results as\nServer-Sent Events until parsing is complete.\n\nPDFs are read via `pdftotext -layout`; text files are decoded as UTF-8.\nPages are separated by the form feed character (`\\f`). If no form feed\nis present, the input is treated as a single page.\n\nThe extracted pages are fed to an LLM (OpenRouter) which fills a structured\nmanifest of header data and line items. The OpenRouter API key is read from\nthe authenticated user's company setting `keys.openrouter` (or the server's\n`OPENROUTER_FREE_KEY` if not configured); the endpoint\nreturns `400` if the key is not configured.\n\nThe stream ends after the final `result` event (or an `error` event on failure).\n",
|
||||||
"security": [
|
"security": [
|
||||||
{
|
{
|
||||||
"cookieAuth": []
|
"cookieAuth": []
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ is present, the input is treated as a single page.
|
|||||||
|
|
||||||
The extracted pages are fed to an LLM (OpenRouter) which fills a structured
|
The extracted pages are fed to an LLM (OpenRouter) which fills a structured
|
||||||
manifest of header data and line items. The OpenRouter API key is read from
|
manifest of header data and line items. The OpenRouter API key is read from
|
||||||
the authenticated user's company setting `keys.openrouter`; the endpoint
|
the authenticated user's company setting `keys.openrouter` (or the server's
|
||||||
|
`OPENROUTER_FREE_KEY` if not configured); the endpoint
|
||||||
returns `400` if the key is not configured.
|
returns `400` if the key is not configured.
|
||||||
|
|
||||||
The stream ends after the final `result` event (or an `error` event on failure).
|
The stream ends after the final `result` event (or an `error` event on failure).
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import multer from 'multer';
|
|||||||
import { LLMOrbiter, OpenRouterProvider, defineTool, DirectReturnError } from 'libllmorbiter';
|
import { LLMOrbiter, OpenRouterProvider, defineTool, DirectReturnError } from 'libllmorbiter';
|
||||||
import * as dbCompanySetting from '../../db/companysetting.js';
|
import * as dbCompanySetting from '../../db/companysetting.js';
|
||||||
import * as dbSupplier from '../../db/supplier.js';
|
import * as dbSupplier from '../../db/supplier.js';
|
||||||
|
import env from '../../config/env.js';
|
||||||
|
|
||||||
// ─── Multer — memory storage (no temp files); accepts PDF or text ───────────────
|
// ─── Multer — memory storage (no temp files); accepts PDF or text ───────────────
|
||||||
const upload = multer({
|
const upload = multer({
|
||||||
@@ -113,14 +114,20 @@ ${supplierList}`;
|
|||||||
* @param {string} opts.sourceLabel e.g. 'PDF' or 'Text'
|
* @param {string} opts.sourceLabel e.g. 'PDF' or 'Text'
|
||||||
*/
|
*/
|
||||||
async function parseDocumentManifest({ req, res, pages, sourceLabel }) {
|
async function parseDocumentManifest({ req, res, pages, sourceLabel }) {
|
||||||
// ── Fetch OpenRouter API key from company settings ────────────────
|
// ── Fetch OpenRouter API key from company settings (or fallback) ──
|
||||||
let apiKey;
|
let apiKey;
|
||||||
try {
|
try {
|
||||||
const setting = await dbCompanySetting.getByKey(req.user.id, 'keys.openrouter', { maskWriteonly: false });
|
const setting = await dbCompanySetting.getByKey(req.user.id, 'keys.openrouter', { maskWriteonly: false });
|
||||||
apiKey = setting?.value;
|
apiKey = setting?.value?.trim();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('delivery parse: failed to read OpenRouter key:', err);
|
console.error('delivery parse: failed to read OpenRouter key:', err);
|
||||||
}
|
}
|
||||||
|
if (!apiKey) {
|
||||||
|
apiKey = env.openrouterFreeKey?.trim();
|
||||||
|
if (apiKey) {
|
||||||
|
console.log('delivery parse: using fallback OPENROUTER_FREE_KEY');
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!apiKey) {
|
if (!apiKey) {
|
||||||
return res.status(400).json({ error: 'OpenRouter API key not configured (companysetting: keys.openrouter)' });
|
return res.status(400).json({ error: 'OpenRouter API key not configured (companysetting: keys.openrouter)' });
|
||||||
}
|
}
|
||||||
@@ -447,7 +454,8 @@ export function register(app, basePath = '') {
|
|||||||
*
|
*
|
||||||
* The extracted pages are fed to an LLM (OpenRouter) which fills a structured
|
* The extracted pages are fed to an LLM (OpenRouter) which fills a structured
|
||||||
* manifest of header data and line items. The OpenRouter API key is read from
|
* manifest of header data and line items. The OpenRouter API key is read from
|
||||||
* the authenticated user's company setting `keys.openrouter`; the endpoint
|
* the authenticated user's company setting `keys.openrouter` (or the server's
|
||||||
|
* `OPENROUTER_FREE_KEY` if not configured); the endpoint
|
||||||
* returns `400` if the key is not configured.
|
* returns `400` if the key is not configured.
|
||||||
*
|
*
|
||||||
* The stream ends after the final `result` event (or an `error` event on failure).
|
* The stream ends after the final `result` event (or an `error` event on failure).
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ export default {
|
|||||||
implicitCreate: process.env.IMPLICIT_CREATE === 'true',
|
implicitCreate: process.env.IMPLICIT_CREATE === 'true',
|
||||||
jwtSecret: process.env.JWT_SECRET || 'fallback_secret_please_change_in_production',
|
jwtSecret: process.env.JWT_SECRET || 'fallback_secret_please_change_in_production',
|
||||||
dbProvider: process.env.DB_PROVIDER || (process.env.SQLITE_PATH ? 'sqlite' : 'mssql'),
|
dbProvider: process.env.DB_PROVIDER || (process.env.SQLITE_PATH ? 'sqlite' : 'mssql'),
|
||||||
|
openrouterFreeKey: process.env.OPENROUTER_FREE_KEY,
|
||||||
sqlite: {
|
sqlite: {
|
||||||
filename: process.env.SQLITE_PATH || process.env.SQLITE_FILENAME || resolve(__dirname, '../../data/dash.db'),
|
filename: process.env.SQLITE_PATH || process.env.SQLITE_FILENAME || resolve(__dirname, '../../data/dash.db'),
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user