aiex-cli 0.0.2-beta.8 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +118 -9
- package/dist/{doctor-collector-PE7lFkhF.mjs → doctor-collector-DR7s0UUh.mjs} +1 -1
- package/dist/index.mjs +1 -1
- package/dist/web/assets/{AISettings-qndQXNRu.js → AISettings-DwXkpWZU.js} +3 -3
- package/dist/web/assets/DataBrowser-Dzdc0ESt.js +6 -0
- package/dist/web/assets/ExtractionViewer-DNcRCmNK.js +1 -0
- package/dist/web/assets/{api-client-BF3HG2Vn.js → api-client-CG1VV5gz.js} +1 -1
- package/dist/web/assets/{index-B2j82TU0.js → index-BpxCXucL.js} +6 -6
- package/dist/web/assets/index-Lx807is2.css +2 -0
- package/dist/web/index.html +3 -3
- package/package.json +1 -1
- package/dist/web/assets/DataBrowser-CwcTG80-.js +0 -6
- package/dist/web/assets/ExtractionViewer-BghKsfo8.js +0 -1
- package/dist/web/assets/index-C9N8oWt4.css +0 -2
package/dist/cli.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as version, T as formatDoctorDiagnosticsJson, _ as createConfig, a as parseJsonSchema, b as name, c as getDefaultAIConfig, d as DEFAULT_MARKITDOWN_CONFIG, f as DEFAULT_MINERU_CONFIG, g as AIConfigSchema, h as PLACEHOLDER_TEXT, i as JsonSchemaDefinitionSchema, l as readAIConfig, m as PLACEHOLDER_SCHEMA, n as createMigrationConfig, o as toSnakeCase, p as DEFAULT_PROMPT_CONFIG, s as generateDrizzleSchema, t as collectDoctorDiagnostics, u as writeAIConfig, v as seedConfig, w as doctorDiagnosticsTableRows, x as package_default, y as description } from "./doctor-collector-
|
|
1
|
+
import { S as version, T as formatDoctorDiagnosticsJson, _ as createConfig, a as parseJsonSchema, b as name, c as getDefaultAIConfig, d as DEFAULT_MARKITDOWN_CONFIG, f as DEFAULT_MINERU_CONFIG, g as AIConfigSchema, h as PLACEHOLDER_TEXT, i as JsonSchemaDefinitionSchema, l as readAIConfig, m as PLACEHOLDER_SCHEMA, n as createMigrationConfig, o as toSnakeCase, p as DEFAULT_PROMPT_CONFIG, s as generateDrizzleSchema, t as collectDoctorDiagnostics, u as writeAIConfig, v as seedConfig, w as doctorDiagnosticsTableRows, x as package_default, y as description } from "./doctor-collector-DR7s0UUh.mjs";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import fs from "node:fs/promises";
|
|
4
4
|
import os from "node:os";
|
|
@@ -14963,6 +14963,8 @@ function aiRoutes(config) {
|
|
|
14963
14963
|
//#endregion
|
|
14964
14964
|
//#region src/server/routes/data.ts
|
|
14965
14965
|
const FILE_REGEX = /\.json$/;
|
|
14966
|
+
const EXTRACTION_TIMESTAMP_RE = /-\d{4}-\d{2}-\d{2}T/;
|
|
14967
|
+
const INTERNAL_ROWID_COLUMN = "__aiex_rowid";
|
|
14966
14968
|
const TIMESTAMP_CLEANUP = /(\d{2})-(\d{2})-(\d{2})/;
|
|
14967
14969
|
const TIMESTAMP_TZ = /(\d{3})Z/;
|
|
14968
14970
|
const tableParamSchema = z.object({ name: z.string().regex(/^[a-z][a-z0-9_]*$/) });
|
|
@@ -14979,6 +14981,37 @@ function invalidParamResponse$1(message) {
|
|
|
14979
14981
|
if (!result.success) return c.json({ error: message }, 400);
|
|
14980
14982
|
};
|
|
14981
14983
|
}
|
|
14984
|
+
function getAuditNotionStatus(record) {
|
|
14985
|
+
if (record.notionPages?.length) return "synced";
|
|
14986
|
+
if (record.status === "failed") return "failed";
|
|
14987
|
+
return "not_synced";
|
|
14988
|
+
}
|
|
14989
|
+
async function getRowExtractionActions(aiexDir, tableName) {
|
|
14990
|
+
const actions = /* @__PURE__ */ new Map();
|
|
14991
|
+
const auditRecords = await listExtractionAuditRecords(aiexDir);
|
|
14992
|
+
for (const record of auditRecords) {
|
|
14993
|
+
if (!record.outputName) continue;
|
|
14994
|
+
for (const inserted of record.tablesInserted ?? []) {
|
|
14995
|
+
if (inserted.table !== tableName) continue;
|
|
14996
|
+
const key = String(inserted.rowId);
|
|
14997
|
+
if (actions.has(key)) continue;
|
|
14998
|
+
const notionPages = record.notionPages?.length ? record.notionPages : void 0;
|
|
14999
|
+
actions.set(key, {
|
|
15000
|
+
extractionName: record.outputName,
|
|
15001
|
+
notionStatus: getAuditNotionStatus(record),
|
|
15002
|
+
notionPages,
|
|
15003
|
+
notionError: !notionPages && record.status === "failed" ? record.error : void 0
|
|
15004
|
+
});
|
|
15005
|
+
}
|
|
15006
|
+
}
|
|
15007
|
+
return actions;
|
|
15008
|
+
}
|
|
15009
|
+
function schemaNameFromExtractionFile(name$1) {
|
|
15010
|
+
const stem = name$1.replace(FILE_REGEX, "");
|
|
15011
|
+
const match = stem.match(EXTRACTION_TIMESTAMP_RE);
|
|
15012
|
+
if (!match || typeof match.index !== "number" || match.index <= 0) return null;
|
|
15013
|
+
return stem.slice(0, match.index);
|
|
15014
|
+
}
|
|
14982
15015
|
function createReadonlyQueryDb(databasePath) {
|
|
14983
15016
|
return new Kysely({ dialect: new SqliteDialect({ database: new Database(databasePath, { readonly: true }) }) });
|
|
14984
15017
|
}
|
|
@@ -14990,22 +15023,27 @@ function dataRoutes(config) {
|
|
|
14990
15023
|
try {
|
|
14991
15024
|
await fs.mkdir(extractedDir, { recursive: true });
|
|
14992
15025
|
const jsonFiles = (await fs.readdir(extractedDir)).filter((f) => f.endsWith(".json") && !f.endsWith(".prompt.md"));
|
|
15026
|
+
const auditRecords = await listExtractionAuditRecords(aiexDir);
|
|
15027
|
+
const auditByOutputName = new Map(auditRecords.map((record) => [record.outputName, record]));
|
|
14993
15028
|
const records = [];
|
|
14994
15029
|
for (const file of jsonFiles) {
|
|
14995
|
-
const
|
|
14996
|
-
|
|
14997
|
-
|
|
14998
|
-
const schemaName = name$1.slice(0, idx);
|
|
14999
|
-
const timestamp = name$1.slice(idx + 1).replace(/-/g, (d, i) => i === 4 || i === 7 ? "-" : d).replace(TIMESTAMP_CLEANUP, (_, h, m, s) => `${h}:${m}:${s}`).replace(TIMESTAMP_TZ, ".$1Z");
|
|
15030
|
+
const schemaName = schemaNameFromExtractionFile(file);
|
|
15031
|
+
if (!schemaName) continue;
|
|
15032
|
+
const timestamp = file.replace(FILE_REGEX, "").slice(schemaName.length + 1).replace(/-/g, (d, i) => i === 4 || i === 7 ? "-" : d).replace(TIMESTAMP_CLEANUP, (_, h, m, s) => `${h}:${m}:${s}`).replace(TIMESTAMP_TZ, ".$1Z");
|
|
15000
15033
|
const filePath = path.join(extractedDir, file);
|
|
15001
15034
|
try {
|
|
15002
15035
|
const stat = await fs.stat(filePath);
|
|
15036
|
+
const audit = auditByOutputName.get(file);
|
|
15037
|
+
const notionPages = audit?.notionPages?.length ? audit.notionPages : void 0;
|
|
15003
15038
|
records.push({
|
|
15004
15039
|
name: file,
|
|
15005
15040
|
schemaName,
|
|
15006
15041
|
timestamp,
|
|
15007
15042
|
fileSize: stat.size,
|
|
15008
|
-
modifiedAt: stat.mtime.toISOString()
|
|
15043
|
+
modifiedAt: stat.mtime.toISOString(),
|
|
15044
|
+
notionStatus: notionPages ? "synced" : audit?.status === "failed" ? "failed" : "not_synced",
|
|
15045
|
+
notionPages,
|
|
15046
|
+
notionError: !notionPages && audit?.status === "failed" ? audit.error : void 0
|
|
15009
15047
|
});
|
|
15010
15048
|
} catch {
|
|
15011
15049
|
continue;
|
|
@@ -15092,16 +15130,24 @@ function dataRoutes(config) {
|
|
|
15092
15130
|
const offset = (page - 1) * pageSize;
|
|
15093
15131
|
const totalPages = Math.max(1, Math.ceil(total / pageSize));
|
|
15094
15132
|
const result = await sql`
|
|
15095
|
-
select *
|
|
15133
|
+
select rowid as ${sql.raw(INTERNAL_ROWID_COLUMN)}, *
|
|
15096
15134
|
from ${sql.table(tableName)}
|
|
15097
15135
|
${searchCondition}
|
|
15098
15136
|
${orderBy}
|
|
15099
15137
|
limit ${pageSize}
|
|
15100
15138
|
offset ${offset}
|
|
15101
15139
|
`.execute(db);
|
|
15140
|
+
const actionsByRowId = await getRowExtractionActions(aiexDir, tableName);
|
|
15141
|
+
const rowActions = Object.fromEntries(result.rows.map((row, index) => {
|
|
15142
|
+
const rowId = row[INTERNAL_ROWID_COLUMN];
|
|
15143
|
+
const action = rowId === null || rowId === void 0 ? void 0 : actionsByRowId.get(String(rowId));
|
|
15144
|
+
return action ? [String(index), action] : null;
|
|
15145
|
+
}).filter((entry) => !!entry));
|
|
15146
|
+
const rows = result.rows.map(({ [INTERNAL_ROWID_COLUMN]: _rowid, ...row }) => row);
|
|
15102
15147
|
return c.json({
|
|
15103
15148
|
columns,
|
|
15104
|
-
rows
|
|
15149
|
+
rows,
|
|
15150
|
+
rowActions,
|
|
15105
15151
|
total,
|
|
15106
15152
|
page,
|
|
15107
15153
|
pageSize,
|
|
@@ -15127,6 +15173,69 @@ function dataRoutes(config) {
|
|
|
15127
15173
|
return c.json({ error: "Extraction result not found" }, 404);
|
|
15128
15174
|
}
|
|
15129
15175
|
});
|
|
15176
|
+
app.post("/data/:name/notion/retry", zValidator("param", extractionFileParamSchema, invalidParamResponse$1("Invalid extraction file name")), async (c) => {
|
|
15177
|
+
const { name: name$1 } = c.req.valid("param");
|
|
15178
|
+
const filePath = path.join(extractedDir, name$1);
|
|
15179
|
+
const schemaName = schemaNameFromExtractionFile(name$1);
|
|
15180
|
+
if (!schemaName) return c.json({
|
|
15181
|
+
success: false,
|
|
15182
|
+
error: "Cannot infer schema name from extraction file name"
|
|
15183
|
+
}, 400);
|
|
15184
|
+
const aiConfig = await readAIConfig(aiexDir);
|
|
15185
|
+
if (!aiConfig?.notion?.enabled) return c.json({
|
|
15186
|
+
success: false,
|
|
15187
|
+
error: "Notion export is not enabled. Configure Notion settings first."
|
|
15188
|
+
}, 400);
|
|
15189
|
+
if (!aiConfig.notion.schemas?.[schemaName]?.databaseId?.trim()) return c.json({
|
|
15190
|
+
success: false,
|
|
15191
|
+
error: `Notion database is not configured for schema "${schemaName}".`
|
|
15192
|
+
}, 400);
|
|
15193
|
+
try {
|
|
15194
|
+
const data = await readFile(filePath);
|
|
15195
|
+
if (!data || typeof data !== "object" || Array.isArray(data)) return c.json({
|
|
15196
|
+
success: false,
|
|
15197
|
+
error: "Extraction result is not a JSON object and cannot be written to Notion."
|
|
15198
|
+
}, 400);
|
|
15199
|
+
const page = await writeNotionPage(aiConfig.notion, schemaName, data);
|
|
15200
|
+
const notionPages = [{
|
|
15201
|
+
databaseId: page.databaseId,
|
|
15202
|
+
pageId: page.pageId
|
|
15203
|
+
}];
|
|
15204
|
+
let record = (await listExtractionAuditRecords(aiexDir)).find((record$1) => record$1.outputName === name$1);
|
|
15205
|
+
if (!record) record = await createExtractionAuditRecord(aiexDir, {
|
|
15206
|
+
schemaName,
|
|
15207
|
+
source: {
|
|
15208
|
+
type: "file",
|
|
15209
|
+
filePath,
|
|
15210
|
+
fileName: name$1
|
|
15211
|
+
}
|
|
15212
|
+
});
|
|
15213
|
+
if (record) await updateExtractionAuditRecord(aiexDir, record.id, {
|
|
15214
|
+
status: "succeeded",
|
|
15215
|
+
outputPath: filePath,
|
|
15216
|
+
outputName: name$1,
|
|
15217
|
+
notionPages,
|
|
15218
|
+
error: void 0
|
|
15219
|
+
});
|
|
15220
|
+
return c.json({
|
|
15221
|
+
success: true,
|
|
15222
|
+
notionPages
|
|
15223
|
+
});
|
|
15224
|
+
} catch (error) {
|
|
15225
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
15226
|
+
const record = (await listExtractionAuditRecords(aiexDir)).find((record$1) => record$1.outputName === name$1);
|
|
15227
|
+
if (record) await updateExtractionAuditRecord(aiexDir, record.id, {
|
|
15228
|
+
status: "failed",
|
|
15229
|
+
outputPath: filePath,
|
|
15230
|
+
outputName: name$1,
|
|
15231
|
+
error: message
|
|
15232
|
+
});
|
|
15233
|
+
return c.json({
|
|
15234
|
+
success: false,
|
|
15235
|
+
error: message
|
|
15236
|
+
}, 500);
|
|
15237
|
+
}
|
|
15238
|
+
});
|
|
15130
15239
|
return app;
|
|
15131
15240
|
}
|
|
15132
15241
|
|
|
@@ -65,7 +65,7 @@ function doctorDiagnosticsTableRows(d) {
|
|
|
65
65
|
//#endregion
|
|
66
66
|
//#region package.json
|
|
67
67
|
var name = "aiex-cli";
|
|
68
|
-
var version = "0.0.2
|
|
68
|
+
var version = "0.0.2";
|
|
69
69
|
var description = "JSON Schema → SQLite with AI-powered data extraction";
|
|
70
70
|
var package_default = {
|
|
71
71
|
name,
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { C as buildDoctorDiagnostics, T as formatDoctorDiagnosticsJson, a as parseJsonSchema, i as JsonSchemaDefinitionSchema, n as createMigrationConfig, r as generateDrizzleConfig, s as generateDrizzleSchema, t as collectDoctorDiagnostics, w as doctorDiagnosticsTableRows } from "./doctor-collector-
|
|
1
|
+
import { C as buildDoctorDiagnostics, T as formatDoctorDiagnosticsJson, a as parseJsonSchema, i as JsonSchemaDefinitionSchema, n as createMigrationConfig, r as generateDrizzleConfig, s as generateDrizzleSchema, t as collectDoctorDiagnostics, w as doctorDiagnosticsTableRows } from "./doctor-collector-DR7s0UUh.mjs";
|
|
2
2
|
|
|
3
3
|
export { JsonSchemaDefinitionSchema, buildDoctorDiagnostics, collectDoctorDiagnostics, createMigrationConfig, doctorDiagnosticsTableRows, formatDoctorDiagnosticsJson, generateDrizzleConfig, generateDrizzleSchema, parseJsonSchema };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{B as e,H as t,Jt as n,K as r,L as ee,Lt as i,M as a,Pn as o,Pt as s,Q as c,R as te,S as l,Sn as u,Tn as d,U as f,W as p,Yt as m,_ as h,c as g,d as ne,et as re,g as _,h as v,ht as y,i as b,in as x,j as S,jn as C,lt as w,m as T,nt as ie,t as E,un as ae,v as D,w as oe,x as O}from"./button-Cdgr9Igy.js";import{i as se,n as k,r as ce,s as A,t as le}from"./dialog-CUkPLPNP.js";import{s as ue,t as de}from"./runtime-dom.esm-bundler-ei_N7Xjw.js";import{a as fe,f as pe,
|
|
1
|
+
import{B as e,H as t,Jt as n,K as r,L as ee,Lt as i,M as a,Pn as o,Pt as s,Q as c,R as te,S as l,Sn as u,Tn as d,U as f,W as p,Yt as m,_ as h,c as g,d as ne,et as re,g as _,h as v,ht as y,i as b,in as x,j as S,jn as C,lt as w,m as T,nt as ie,t as E,un as ae,v as D,w as oe,x as O}from"./button-Cdgr9Igy.js";import{i as se,n as k,r as ce,s as A,t as le}from"./dialog-CUkPLPNP.js";import{s as ue,t as de}from"./runtime-dom.esm-bundler-ei_N7Xjw.js";import{_ as j,a as fe,f as pe,m as me,n as he,s as ge}from"./api-client-CG1VV5gz.js";import{i as M,n as N,o as P,r as F,t as _e}from"./select-BGex2SPs.js";var I={name:`MinusIcon`,extends:b};function L(e){return B(e)||z(e)||R(e)||ve()}function ve(){throw TypeError(`Invalid attempt to spread non-iterable instance.
|
|
2
2
|
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function R(e,t){if(e){if(typeof e==`string`)return V(e,t);var n={}.toString.call(e).slice(8,-1);return n===`Object`&&e.constructor&&(n=e.constructor.name),n===`Map`||n===`Set`?Array.from(e):n===`Arguments`||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?V(e,t):void 0}}function z(e){if(typeof Symbol<`u`&&e[Symbol.iterator]!=null||e[`@@iterator`]!=null)return Array.from(e)}function B(e){if(Array.isArray(e))return V(e)}function V(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function H(t,n,r,ee,i,o){return e(),D(`svg`,a({width:`14`,height:`14`,viewBox:`0 0 14 14`,fill:`none`,xmlns:`http://www.w3.org/2000/svg`},t.pti()),L(n[0]||=[v(`path`,{d:`M13.2222 7.77778H0.777778C0.571498 7.77778 0.373667 7.69584 0.227806 7.54998C0.0819442 7.40412 0 7.20629 0 7.00001C0 6.79373 0.0819442 6.5959 0.227806 6.45003C0.373667 6.30417 0.571498 6.22223 0.777778 6.22223H13.2222C13.4285 6.22223 13.6263 6.30417 13.7722 6.45003C13.9181 6.5959 14 6.79373 14 7.00001C14 7.20629 13.9181 7.40412 13.7722 7.54998C13.6263 7.69584 13.4285 7.77778 13.2222 7.77778Z`,fill:`currentColor`},null,-1)]),16)}I.render=H;var U=g.extend({name:`checkbox`,style:`
|
|
3
3
|
.p-checkbox {
|
|
4
4
|
position: relative;
|
|
@@ -336,9 +336,9 @@ Extraction requirements:
|
|
|
336
336
|
-o
|
|
337
337
|
{outputDir}`),ae=w(600),oe=w(!0),se=w(!0),k=w(`markitdown`),ce=w(`{input}
|
|
338
338
|
-o
|
|
339
|
-
{outputDir}/{basename}.md`),A=w(`{outputDir}/{basename}.md`),de=w(600),M=w(!0),N=w(!0),P=w(!1),I=w(``),L=w(``),ve=w(``),R=w(!1),z=w(``),B=w({}),V=w(``),H=w(``),U=w(``),W=w(``),G=w(!1),K=w([]),q=w([]),ye=w(!1),be=w(!1),J=w(``),Y=w({vision:!1,structuredOutput:!1}),xe=w(`manual`);function Se(){xe.value=`manual`,Y.value={vision:!1,structuredOutput:!1},J.value&&pe(J.value).then(e=>{e&&(Y.value={...e},xe.value=`registry`)})}function Ce(){J.value&&(m.value.push({name:J.value,capabilities:{...Y.value}}),Te())}function we(){Te()}function Te(){J.value=``,Y.value={vision:!1,structuredOutput:!1},xe.value=`manual`,be.value=!1}function Ee(e){m.value.splice(e,1)}let De=T(()=>g.value.includes(`{schema}`)?``:`System prompt must contain the {schema} placeholder`),Oe=T(()=>b.value.includes(`{text}`)?``:`User prompt must contain the {text} placeholder`),ke=T(()=>r.schemas.map(e=>e.replace(`.json`,``))),Z=T(()=>{let e=W.value.trim();if(!e)return``;try{let t=JSON.parse(e);if(!t||typeof t!=`object`||Array.isArray(t))return`Field map must be a JSON object`;for(let[e,n]of Object.entries(t))if(typeof n!=`string`)return`Field map value for "${e}" must be a string`;return``}catch{return`Field map must be valid JSON`}}),Ae=T(()=>{try{return Object.keys(Q()??{}).length}catch{return 0}}),je=T(()=>K.value.length===0?``:q.value.length===0?`Connected · ${K.value.length} properties loaded`:`Connected · ${Ae.value}/${q.value.length} fields mapped`),Me=T(()=>!De.value&&!Oe.value&&!Z.value&&!o.value&&m.value.length>0&&(!R.value||!!z.value.trim())&&(x.value!==`mineru`||!!S.value.trim())&&(x.value!==`markitdown`||!!k.value.trim()));function Q(){if(!W.value.trim())return;let e=JSON.parse(W.value),t=Object.fromEntries(Object.entries(e).map(([e,t])=>[e,typeof t==`string`?t.trim():``]).filter(([e,t])=>!!e&&!!t));return Object.keys(t).length>0?t:void 0}function Ne(e){if(!e?.properties||typeof e.properties!=`object`)return[];let t=[];function n(e,r=``){for(let[ee,i]of Object.entries(e)){let e=r?`${r}.${ee}`:ee;if(i?.type===`object`&&i?.properties&&typeof i.properties==`object`){n(i.properties,e);continue}i?.type===`array`&&i?.items?.type===`object`||t.push(e)}}return n(e.properties),t}function Pe(e){let t={};for(let n of q.value)t[n]=e?.[n]??``;for(let[n,r]of Object.entries(e??{}))n in t||(t[n]=r);return Object.keys(t).length>0?JSON.stringify(t,null,2):``}function Fe(e=V.value){if(!e||Z.value)return;let t=H.value.trim(),n=U.value.trim(),r=Q();if(!t){let t={...B.value};delete t[e],B.value=t;return}B.value={...B.value,[e]:{databaseId:t,titleProperty:n||void 0,fieldMap:r}}}function Ie(){let e=V.value?B.value[V.value]:void 0;H.value=e?.databaseId??``,U.value=e?.titleProperty??``,W.value=Pe(e?.fieldMap),K.value=[]}re(ke,e=>{!V.value&&e.length>0&&(V.value=e[0])},{immediate:!0}),re(V,(e,t)=>{t&&Fe(t),Le()});async function Le(){let e=V.value;if(q.value=[],!e){Ie();return}try{q.value=Ne(await fe(`${e}.json`))}catch{q.value=[]}Ie()}let Re=[{label:`Built-in text extraction`,value:`unpdf`},{label:`MinerU command`,value:`mineru`},{label:`MarkItDown command`,value:`markitdown`}];async function ze(){o.value=!0;try{let e=await
|
|
339
|
+
{outputDir}/{basename}.md`),A=w(`{outputDir}/{basename}.md`),de=w(600),M=w(!0),N=w(!0),P=w(!1),I=w(``),L=w(``),ve=w(``),R=w(!1),z=w(``),B=w({}),V=w(``),H=w(``),U=w(``),W=w(``),G=w(!1),K=w([]),q=w([]),ye=w(!1),be=w(!1),J=w(``),Y=w({vision:!1,structuredOutput:!1}),xe=w(`manual`);function Se(){xe.value=`manual`,Y.value={vision:!1,structuredOutput:!1},J.value&&pe(J.value).then(e=>{e&&(Y.value={...e},xe.value=`registry`)})}function Ce(){J.value&&(m.value.push({name:J.value,capabilities:{...Y.value}}),Te())}function we(){Te()}function Te(){J.value=``,Y.value={vision:!1,structuredOutput:!1},xe.value=`manual`,be.value=!1}function Ee(e){m.value.splice(e,1)}let De=T(()=>g.value.includes(`{schema}`)?``:`System prompt must contain the {schema} placeholder`),Oe=T(()=>b.value.includes(`{text}`)?``:`User prompt must contain the {text} placeholder`),ke=T(()=>r.schemas.map(e=>e.replace(`.json`,``))),Z=T(()=>{let e=W.value.trim();if(!e)return``;try{let t=JSON.parse(e);if(!t||typeof t!=`object`||Array.isArray(t))return`Field map must be a JSON object`;for(let[e,n]of Object.entries(t))if(typeof n!=`string`)return`Field map value for "${e}" must be a string`;return``}catch{return`Field map must be valid JSON`}}),Ae=T(()=>{try{return Object.keys(Q()??{}).length}catch{return 0}}),je=T(()=>K.value.length===0?``:q.value.length===0?`Connected · ${K.value.length} properties loaded`:`Connected · ${Ae.value}/${q.value.length} fields mapped`),Me=T(()=>!De.value&&!Oe.value&&!Z.value&&!o.value&&m.value.length>0&&(!R.value||!!z.value.trim())&&(x.value!==`mineru`||!!S.value.trim())&&(x.value!==`markitdown`||!!k.value.trim()));function Q(){if(!W.value.trim())return;let e=JSON.parse(W.value),t=Object.fromEntries(Object.entries(e).map(([e,t])=>[e,typeof t==`string`?t.trim():``]).filter(([e,t])=>!!e&&!!t));return Object.keys(t).length>0?t:void 0}function Ne(e){if(!e?.properties||typeof e.properties!=`object`)return[];let t=[];function n(e,r=``){for(let[ee,i]of Object.entries(e)){let e=r?`${r}.${ee}`:ee;if(i?.type===`object`&&i?.properties&&typeof i.properties==`object`){n(i.properties,e);continue}i?.type===`array`&&i?.items?.type===`object`||t.push(e)}}return n(e.properties),t}function Pe(e){let t={};for(let n of q.value)t[n]=e?.[n]??``;for(let[n,r]of Object.entries(e??{}))n in t||(t[n]=r);return Object.keys(t).length>0?JSON.stringify(t,null,2):``}function Fe(e=V.value){if(!e||Z.value)return;let t=H.value.trim(),n=U.value.trim(),r=Q();if(!t){let t={...B.value};delete t[e],B.value=t;return}B.value={...B.value,[e]:{databaseId:t,titleProperty:n||void 0,fieldMap:r}}}function Ie(){let e=V.value?B.value[V.value]:void 0;H.value=e?.databaseId??``,U.value=e?.titleProperty??``,W.value=Pe(e?.fieldMap),K.value=[]}re(ke,e=>{!V.value&&e.length>0&&(V.value=e[0])},{immediate:!0}),re(V,(e,t)=>{t&&Fe(t),Le()});async function Le(){let e=V.value;if(q.value=[],!e){Ie();return}try{q.value=Ne(await fe(`${e}.json`))}catch{q.value=[]}Ie()}let Re=[{label:`Built-in text extraction`,value:`unpdf`},{label:`MinerU command`,value:`mineru`},{label:`MarkItDown command`,value:`markitdown`}];async function ze(){o.value=!0;try{let e=await he();d.value=e.provider.baseURL,f.value=e.provider.apiKey,p.value=e.provider.timeout??300,m.value=e.provider.models??[],g.value=e.prompt.systemTemplate,b.value=e.prompt.userTemplate,x.value=e.pdf?.converter??`unpdf`,S.value=e.pdf?.mineru?.command??`mineru`,C.value=(e.pdf?.mineru?.args??[`-p`,`{input}`,`-o`,`{outputDir}`]).join(`
|
|
340
340
|
`),ae.value=e.pdf?.mineru?.timeout??600,oe.value=e.pdf?.mineru?.fallbackToUnpdf??!0,se.value=e.pdf?.mineru?.keepOutput??!0,k.value=e.pdf?.markitdown?.command??`markitdown`,ce.value=(e.pdf?.markitdown?.args??[`{input}`,`-o`,`{outputDir}/{basename}.md`]).join(`
|
|
341
|
-
`),A.value=e.pdf?.markitdown?.outputFile??`{outputDir}/{basename}.md`,de.value=e.pdf?.markitdown?.timeout??600,M.value=e.pdf?.markitdown?.fallbackToUnpdf??!0,N.value=e.pdf?.markitdown?.keepOutput??!0,P.value=!!e.langfuse,I.value=e.langfuse?.publicKey??``,L.value=e.langfuse?.secretKey??``,ve.value=e.langfuse?.host??``,R.value=!!e.notion?.enabled,z.value=e.notion?.token??``,B.value=e.notion?.schemas??{},await Le()}catch{f.value=``,m.value=[],g.value=gn,b.value=_n}finally{o.value=!1}}async function Be(){if(Me.value){u.value=!0;try{Fe(),await
|
|
341
|
+
`),A.value=e.pdf?.markitdown?.outputFile??`{outputDir}/{basename}.md`,de.value=e.pdf?.markitdown?.timeout??600,M.value=e.pdf?.markitdown?.fallbackToUnpdf??!0,N.value=e.pdf?.markitdown?.keepOutput??!0,P.value=!!e.langfuse,I.value=e.langfuse?.publicKey??``,L.value=e.langfuse?.secretKey??``,ve.value=e.langfuse?.host??``,R.value=!!e.notion?.enabled,z.value=e.notion?.token??``,B.value=e.notion?.schemas??{},await Le()}catch{f.value=``,m.value=[],g.value=gn,b.value=_n}finally{o.value=!1}}async function Be(){if(Me.value){u.value=!0;try{Fe(),await me({provider:{baseURL:d.value,apiKey:f.value,timeout:p.value,models:m.value},prompt:{systemTemplate:g.value,userTemplate:b.value},extraction:{outputDir:`.aiex/extracted`},pdf:{converter:x.value,mineru:{command:S.value,args:C.value.split(`
|
|
342
342
|
`).map(e=>e.trim()).filter(Boolean),timeout:ae.value,fallbackToUnpdf:oe.value,keepOutput:se.value||void 0},markitdown:{command:k.value,args:ce.value.split(`
|
|
343
343
|
`).map(e=>e.trim()).filter(Boolean),outputFile:A.value.trim()||void 0,timeout:de.value,fallbackToUnpdf:M.value,keepOutput:N.value||void 0}},langfuse:P.value?{publicKey:I.value,secretKey:L.value,host:ve.value||void 0}:void 0,notion:{enabled:R.value,token:z.value,schemas:B.value}}),a.value=!1}catch(e){j.error(e.message||`Failed to save`)}finally{u.value=!1}}}async function Ve(){if(!V.value){j.error(`Select a schema first`);return}if(!z.value.trim()){j.error(`Enter a Notion integration token`);return}if(!H.value.trim()){j.error(`Enter a Notion database or data source URL/ID`);return}if(Z.value){j.error(Z.value);return}G.value=!0;try{let e=await ge({token:z.value,databaseId:H.value,schemaName:V.value});(e.dataSourceId||e.databaseId)&&(H.value=e.dataSourceId??e.databaseId??``),!U.value&&e.titleProperty&&(U.value=e.titleProperty);let t=Q()??{},n={...e.suggestedFieldMap??{},...t};W.value=Object.keys(n).length>0?JSON.stringify(n,null,2):``,K.value=e.properties??[],Fe(),j.success(`Connected to Notion (${K.value.length} properties)`)}catch(e){j.error(e instanceof Error?e.message:`Notion connection failed`)}finally{G.value=!1}}return ee(()=>{ze()}),te(()=>{}),(n,r)=>(e(),_(y(le),{visible:a.value,"onUpdate:visible":r[33]||=e=>a.value=e,modal:``,header:`AI Settings`,style:{width:`680px`},draggable:!1},{footer:ie(()=>[v(`div`,hn,[l(y(E),{label:`Cancel`,severity:`secondary`,text:``,onClick:r[32]||=e=>a.value=!1}),l(y(E),{label:`Save`,icon:`pi pi-check`,loading:u.value,disabled:!Me.value,onClick:Be},null,8,[`loading`,`disabled`])])]),default:ie(()=>[o.value?(e(),D(`div`,pt,[...r[34]||=[v(`i`,{class:`pi pi-spin pi-spinner text-xl`},null,-1)]])):(e(),D(`div`,mt,[v(`section`,null,[r[38]||=v(`h3`,{class:`text-sm font-semibold mb-3 text-foreground`},` Provider `,-1),v(`div`,ht,[v(`div`,gt,[r[35]||=v(`label`,{class:`text-xs text-muted-foreground`},`Base URL`,-1),l(y(F),{modelValue:d.value,"onUpdate:modelValue":r[0]||=e=>d.value=e,size:`small`,placeholder:`https://dashscope.aliyuncs.com/compatible-mode/v1`},null,8,[`modelValue`])]),v(`div`,_t,[r[36]||=v(`label`,{class:`text-xs text-muted-foreground`},`API Key`,-1),l(y(Je),{modelValue:f.value,"onUpdate:modelValue":r[1]||=e=>f.value=e,feedback:!1,"toggle-mask":``,size:`small`,placeholder:`sk-xxx`,"input-class":`w-full`},null,8,[`modelValue`])]),v(`div`,vt,[r[37]||=v(`label`,{class:`text-xs text-muted-foreground`},`Timeout (seconds)`,-1),l(y(F),{value:String(p.value),type:`number`,size:`small`,placeholder:`300`,min:1,onInput:r[2]||=e=>p.value=Number(e.target.value)||300},null,8,[`value`])])])]),v(`section`,null,[r[40]||=v(`h3`,{class:`text-sm font-semibold mb-3 text-foreground`},` Models `,-1),v(`div`,yt,[(e(!0),D(ne,null,t(m.value,(t,n)=>(e(),D(`div`,{key:n,class:`flex items-center gap-2 px-3 py-2 rounded border border-border bg-card`},[v(`code`,bt,i(t.name),1),v(`span`,{class:s([`inline-flex items-center gap-1 text-xs px-1.5 py-0.5 rounded`,t.capabilities.structuredOutput?`bg-green-500/10 text-green-600`:`bg-yellow-500/10 text-yellow-600`])},[v(`i`,{class:s([t.capabilities.structuredOutput?`pi pi-check-circle`:`pi pi-exclamation-triangle`,`text-[10px]`])},null,2),O(` `+i(t.capabilities.structuredOutput?`Structured Output`:`Text-only Output`),1)],2),v(`span`,{class:s([`inline-flex items-center gap-1 text-xs px-1.5 py-0.5 rounded`,t.capabilities.vision?`bg-green-500/10 text-green-600`:`bg-red-500/10 text-red-600`])},[v(`i`,{class:s([t.capabilities.vision?`pi pi-check-circle`:`pi pi-times-circle`,`text-[10px]`])},null,2),O(` `+i(t.capabilities.vision?`Vision Supported`:`Vision Unsupported`),1)],2),l(y(E),{icon:`pi pi-times`,severity:`danger`,text:``,size:`small`,onClick:e=>Ee(n)},null,8,[`onClick`])]))),128)),be.value?(e(),D(`div`,xt,[v(`div`,St,[l(y(F),{modelValue:J.value,"onUpdate:modelValue":r[3]||=e=>J.value=e,size:`small`,placeholder:`Model name (e.g. gpt-4o)`,class:`flex-1 font-mono`,onInput:Se,onKeyup:ue(Ce,[`enter`])},null,8,[`modelValue`]),l(y(E),{icon:`pi pi-check`,severity:`success`,text:``,size:`small`,disabled:!J.value,onClick:Ce},null,8,[`disabled`]),l(y(E),{icon:`pi pi-times`,severity:`secondary`,text:``,size:`small`,onClick:we})]),v(`div`,Ct,[v(`label`,wt,[l(y(X),{modelValue:Y.value.structuredOutput,"onUpdate:modelValue":r[4]||=e=>Y.value.structuredOutput=e,binary:!0,"input-id":`add-so`},null,8,[`modelValue`]),v(`span`,{class:s(Y.value.structuredOutput?`text-green-600`:`text-muted-foreground`)},` Structured Output `,2)]),v(`label`,Tt,[l(y(X),{modelValue:Y.value.vision,"onUpdate:modelValue":r[5]||=e=>Y.value.vision=e,binary:!0,"input-id":`add-vision`},null,8,[`modelValue`]),v(`span`,{class:s(Y.value.vision?`text-green-600`:`text-muted-foreground`)},` Vision `,2)]),xe.value===`registry`?(e(),D(`span`,Et,[...r[39]||=[v(`i`,{class:`pi pi-database mr-0.5`},null,-1),O(`Registry `,-1)]])):h(``,!0)])])):(e(),_(y(E),{key:1,label:`Add Model`,icon:`pi pi-plus`,severity:`secondary`,text:``,size:`small`,onClick:r[6]||=e=>be.value=!0}))])]),v(`section`,null,[r[55]||=v(`h3`,{class:`text-sm font-semibold mb-3 text-foreground`},` PDF Conversion `,-1),v(`div`,Dt,[v(`div`,Ot,[r[41]||=v(`label`,{class:`text-xs text-muted-foreground`},`Converter`,-1),l(y(_e),{modelValue:x.value,"onUpdate:modelValue":r[7]||=e=>x.value=e,options:Re,"option-label":`label`,"option-value":`value`,size:`small`},null,8,[`modelValue`])]),x.value===`mineru`?(e(),D(`div`,kt,[v(`div`,At,[r[42]||=v(`label`,{class:`text-xs text-muted-foreground`},`Command`,-1),l(y(F),{modelValue:S.value,"onUpdate:modelValue":r[8]||=e=>S.value=e,size:`small`,placeholder:`mineru`},null,8,[`modelValue`])]),v(`div`,jt,[r[43]||=v(`label`,{class:`text-xs text-muted-foreground`},`Arguments`,-1),l(y($),{modelValue:C.value,"onUpdate:modelValue":r[9]||=e=>C.value=e,rows:`4`,"auto-resize":``,class:`text-xs font-mono`},null,8,[`modelValue`])]),v(`div`,Mt,[r[44]||=v(`label`,{class:`text-xs text-muted-foreground`},`Timeout (seconds)`,-1),l(y(F),{value:String(ae.value),type:`number`,size:`small`,placeholder:`600`,min:1,onInput:r[10]||=e=>ae.value=Number(e.target.value)||600},null,8,[`value`])]),v(`div`,Nt,[l(y(X),{modelValue:oe.value,"onUpdate:modelValue":r[11]||=e=>oe.value=e,binary:!0,"input-id":`mineru-fallback`},null,8,[`modelValue`]),r[45]||=v(`label`,{for:`mineru-fallback`,class:`text-sm cursor-pointer`},`Fallback to built-in converter`,-1)]),v(`div`,Pt,[l(y(X),{modelValue:se.value,"onUpdate:modelValue":r[12]||=e=>se.value=e,binary:!0,"input-id":`mineru-keep-output`},null,8,[`modelValue`]),r[46]||=v(`label`,{for:`mineru-keep-output`,class:`text-sm cursor-pointer`},`Keep converted files on disk`,-1)]),r[47]||=v(`div`,{class:`text-xs text-muted-foreground p-2 rounded border border-border`},[O(` Placeholders: `),v(`code`,{class:`bg-secondary px-1 rounded`},`{input}`),O(`, `),v(`code`,{class:`bg-secondary px-1 rounded`},`{outputDir}`),O(`, `),v(`code`,{class:`bg-secondary px-1 rounded`},`{basename}`)],-1)])):h(``,!0),x.value===`markitdown`?(e(),D(`div`,Ft,[v(`div`,It,[r[48]||=v(`label`,{class:`text-xs text-muted-foreground`},`Command`,-1),l(y(F),{modelValue:k.value,"onUpdate:modelValue":r[13]||=e=>k.value=e,size:`small`,placeholder:`markitdown`},null,8,[`modelValue`])]),v(`div`,Lt,[r[49]||=v(`label`,{class:`text-xs text-muted-foreground`},`Arguments`,-1),l(y($),{modelValue:ce.value,"onUpdate:modelValue":r[14]||=e=>ce.value=e,rows:`4`,"auto-resize":``,class:`text-xs font-mono`},null,8,[`modelValue`])]),v(`div`,Rt,[r[50]||=v(`label`,{class:`text-xs text-muted-foreground`},`Output File`,-1),l(y(F),{modelValue:A.value,"onUpdate:modelValue":r[15]||=e=>A.value=e,size:`small`,class:`text-xs font-mono`,placeholder:`{outputDir}/{basename}.md`},null,8,[`modelValue`])]),v(`div`,zt,[r[51]||=v(`label`,{class:`text-xs text-muted-foreground`},`Timeout (seconds)`,-1),l(y(F),{value:String(de.value),type:`number`,size:`small`,placeholder:`600`,min:1,onInput:r[16]||=e=>de.value=Number(e.target.value)||600},null,8,[`value`])]),v(`div`,Bt,[l(y(X),{modelValue:M.value,"onUpdate:modelValue":r[17]||=e=>M.value=e,binary:!0,"input-id":`markitdown-fallback`},null,8,[`modelValue`]),r[52]||=v(`label`,{for:`markitdown-fallback`,class:`text-sm cursor-pointer`},`Fallback to built-in converter`,-1)]),v(`div`,Vt,[l(y(X),{modelValue:N.value,"onUpdate:modelValue":r[18]||=e=>N.value=e,binary:!0,"input-id":`markitdown-keep-output`},null,8,[`modelValue`]),r[53]||=v(`label`,{for:`markitdown-keep-output`,class:`text-sm cursor-pointer`},`Keep converted files on disk`,-1)]),r[54]||=v(`div`,{class:`text-xs text-muted-foreground p-2 rounded border border-border`},[O(` Placeholders: `),v(`code`,{class:`bg-secondary px-1 rounded`},`{input}`),O(`, `),v(`code`,{class:`bg-secondary px-1 rounded`},`{outputDir}`),O(`, `),v(`code`,{class:`bg-secondary px-1 rounded`},`{basename}`)],-1)])):h(``,!0)])]),v(`section`,null,[r[60]||=v(`h3`,{class:`text-sm font-semibold mb-3 text-foreground`},` Langfuse Tracing `,-1),v(`div`,Ht,[v(`div`,Ut,[l(y(X),{modelValue:P.value,"onUpdate:modelValue":r[19]||=e=>P.value=e,binary:!0,"input-id":`lf-enabled`},null,8,[`modelValue`]),r[56]||=v(`label`,{for:`lf-enabled`,class:`text-sm cursor-pointer`},`Enabled`,-1)]),P.value?(e(),D(`div`,Wt,[v(`div`,Gt,[r[57]||=v(`label`,{class:`text-xs text-muted-foreground`},`Secret Key`,-1),l(y(Je),{modelValue:L.value,"onUpdate:modelValue":r[20]||=e=>L.value=e,feedback:!1,"toggle-mask":``,size:`small`,placeholder:`sk-lf-...`,"input-class":`w-full`},null,8,[`modelValue`])]),v(`div`,Kt,[r[58]||=v(`label`,{class:`text-xs text-muted-foreground`},`Public Key`,-1),l(y(F),{modelValue:I.value,"onUpdate:modelValue":r[21]||=e=>I.value=e,size:`small`,placeholder:`pk-lf-...`},null,8,[`modelValue`])]),v(`div`,qt,[r[59]||=v(`label`,{class:`text-xs text-muted-foreground`},`Host (optional)`,-1),l(y(F),{modelValue:ve.value,"onUpdate:modelValue":r[22]||=e=>ve.value=e,size:`small`,placeholder:`https://us.cloud.langfuse.com`},null,8,[`modelValue`])])])):h(``,!0)])]),v(`section`,null,[r[69]||=v(`h3`,{class:`text-sm font-semibold mb-3 text-foreground`},` Notion Export `,-1),v(`div`,Jt,[v(`div`,Yt,[l(y(X),{modelValue:R.value,"onUpdate:modelValue":r[23]||=e=>R.value=e,binary:!0,"input-id":`notion-enabled`},null,8,[`modelValue`]),r[61]||=v(`label`,{for:`notion-enabled`,class:`text-sm cursor-pointer`},`Enabled`,-1)]),v(`div`,Xt,[v(`div`,Zt,[r[62]||=v(`label`,{class:`text-xs text-muted-foreground`},`Integration Token`,-1),l(y(Je),{modelValue:z.value,"onUpdate:modelValue":r[24]||=e=>z.value=e,feedback:!1,"toggle-mask":``,size:`small`,placeholder:`secret_...`,"input-class":`w-full`},null,8,[`modelValue`])]),v(`div`,Qt,[r[63]||=v(`label`,{class:`text-xs text-muted-foreground`},`Schema Binding`,-1),l(y(_e),{modelValue:V.value,"onUpdate:modelValue":r[25]||=e=>V.value=e,options:ke.value,size:`small`,placeholder:`Select a schema`,disabled:ke.value.length===0},null,8,[`modelValue`,`options`,`disabled`])]),v(`div`,$t,[r[64]||=v(`label`,{class:`text-xs text-muted-foreground`},`Database/Data Source URL or ID`,-1),l(y(F),{modelValue:H.value,"onUpdate:modelValue":r[26]||=e=>H.value=e,size:`small`,placeholder:`https://www.notion.so/... or xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx`},null,8,[`modelValue`])]),v(`div`,en,[l(y(E),{label:`Connect & Map`,icon:`pi pi-bolt`,severity:`secondary`,size:`small`,loading:G.value,disabled:!V.value||!z.value.trim()||!H.value.trim()||!!Z.value,onClick:Ve},null,8,[`loading`,`disabled`]),je.value?(e(),D(`span`,tn,i(je.value),1)):h(``,!0)]),v(`div`,nn,[v(`button`,{type:`button`,class:`w-full flex items-center justify-between gap-2 px-3 py-2 text-left text-xs text-muted-foreground hover:bg-secondary`,onClick:r[27]||=e=>ye.value=!ye.value},[r[65]||=v(`span`,null,`Advanced mapping`,-1),v(`i`,{class:s([ye.value?`pi pi-chevron-up`:`pi pi-chevron-down`,`text-[10px]`])},null,2)]),ye.value?(e(),D(`div`,rn,[v(`div`,an,[r[66]||=v(`label`,{class:`text-xs text-muted-foreground`},`Title Property (optional)`,-1),l(y(F),{modelValue:U.value,"onUpdate:modelValue":r[28]||=e=>U.value=e,size:`small`,placeholder:`Name`},null,8,[`modelValue`])]),v(`div`,on,[v(`div`,sn,[r[67]||=v(`label`,{class:`text-xs text-muted-foreground`},`Field Map JSON`,-1),q.value.length>0?(e(),D(`span`,cn,i(Ae.value)+` / `+i(q.value.length)+` mapped `,1)):h(``,!0)]),l(y($),{modelValue:W.value,"onUpdate:modelValue":r[29]||=e=>W.value=e,rows:`5`,"auto-resize":``,class:`text-xs font-mono`,placeholder:`{
|
|
344
344
|
"invoiceNo": "Invoice No",
|