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 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-PE7lFkhF.mjs";
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 name$1 = file.replace(FILE_REGEX, "");
14996
- const idx = name$1.lastIndexOf("-");
14997
- if (idx === -1) continue;
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: result.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-beta.8";
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-PE7lFkhF.mjs";
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,g as j,n as me,p as he,s as ge}from"./api-client-BF3HG2Vn.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.
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 me();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(`
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 he({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(`
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",