aiex-cli 0.0.5-beta.6 → 0.0.6-beta.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.
@@ -74,7 +74,7 @@ function doctorDiagnosticsTableRows(d) {
74
74
  //#endregion
75
75
  //#region package.json
76
76
  var name = "aiex-cli";
77
- var version = "0.0.5-beta.6";
77
+ var version = "0.0.6-beta.2";
78
78
  var description = "JSON Schema → SQLite with AI-powered data extraction";
79
79
  var package_default = {
80
80
  name,
@@ -155,14 +155,13 @@ var package_default = {
155
155
  "es-toolkit": "catalog:",
156
156
  "esbuild": "catalog:",
157
157
  "execa": "catalog:",
158
+ "file-type": "catalog:",
158
159
  "hono": "catalog:",
159
160
  "i18next": "catalog:",
160
161
  "i18next-fs-backend": "catalog:",
161
- "js-tiktoken": "catalog:",
162
162
  "jsonfile": "catalog:",
163
163
  "jsonrepair": "catalog:",
164
164
  "kysely": "catalog:",
165
- "marked": "catalog:",
166
165
  "mime": "catalog:",
167
166
  "open": "catalog:",
168
167
  "p-retry": "catalog:",
@@ -211,6 +210,7 @@ function seedConfig(config = createConfig()) {
211
210
  //#endregion
212
211
  //#region src/core/ai-extraction/schemas.ts
213
212
  const ModelCapabilitiesSchema = z.object({
213
+ vision: z.boolean(),
214
214
  structuredOutput: z.boolean(),
215
215
  maxTokens: z.number().int().positive().optional(),
216
216
  maxOutputTokens: z.number().int().positive().optional()
@@ -229,19 +229,15 @@ const PromptConfigSchema = z.object({
229
229
  systemTemplate: z.string().min(1),
230
230
  userTemplate: z.string().min(1)
231
231
  });
232
- const ExtractionConfigSchema = z.object({
233
- outputDir: z.string().min(1),
234
- mode: z.enum(["pipeline"]).default("pipeline").optional(),
235
- concurrency: z.number().int().min(1).optional(),
236
- maxTokens: z.number().int().positive().default(8e3).optional(),
237
- overlapSize: z.number().int().nonnegative().optional()
238
- });
232
+ const ExtractionConfigSchema = z.object({ outputDir: z.string().min(1) });
233
+ const ImageOcrFallbackSchema = z.preprocess((value) => [
234
+ "auto",
235
+ "off",
236
+ "local"
237
+ ].includes(String(value)) ? "localAuto" : value, z.literal("localAuto").default("localAuto").optional());
239
238
  const ImageOcrConfigSchema = z.object({
240
- imageConversion: z.enum(["vision", "local"]).default("local").optional(),
241
- visionBaseURL: z.string().url().optional(),
242
- visionApiKey: z.string().optional(),
243
- imageModelName: z.string().min(1).optional(),
244
- ocrLanguages: z.string().optional(),
239
+ ocrFallback: ImageOcrFallbackSchema,
240
+ ocrLanguages: z.string().min(1).optional(),
245
241
  ocrMinConfidence: z.number().min(0).max(1).optional()
246
242
  });
247
243
  const ExternalPdfConverterConfigSchema = z.object({
@@ -259,7 +255,20 @@ const MineruApiPdfConverterConfigSchema = z.object({
259
255
  enableFormula: z.boolean().optional(),
260
256
  enableTable: z.boolean().optional()
261
257
  });
262
- const PdfConfigSchema = z.object({
258
+ const PdfConfigSchema = z.preprocess((value) => {
259
+ if (!value || typeof value !== "object") return value;
260
+ const config = { ...value };
261
+ if (config.converter === "markitdown" && config.markitdown) {
262
+ config.converter = "external";
263
+ config.external = config.markitdown;
264
+ } else if (config.converter === "marker" && config.marker) {
265
+ config.converter = "external";
266
+ config.external = config.marker;
267
+ } else if (config.converter === "markitdown" || config.converter === "marker") config.converter = "unpdf";
268
+ delete config.markitdown;
269
+ delete config.marker;
270
+ return config;
271
+ }, z.object({
263
272
  converter: z.enum([
264
273
  "unpdf",
265
274
  "mineru",
@@ -269,7 +278,7 @@ const PdfConfigSchema = z.object({
269
278
  mineru: ExternalPdfConverterConfigSchema.optional(),
270
279
  mineruApi: MineruApiPdfConverterConfigSchema.optional(),
271
280
  external: ExternalPdfConverterConfigSchema.optional()
272
- });
281
+ }));
273
282
  const LangfuseConfigSchema = z.object({
274
283
  publicKey: z.string(),
275
284
  secretKey: z.string(),
@@ -307,7 +316,16 @@ const PLACEHOLDER_SCHEMA = "{schema}";
307
316
  const PLACEHOLDER_TEXT = "{text}";
308
317
  const DEFAULT_MODELS = [{
309
318
  name: "qwen-plus",
310
- capabilities: { structuredOutput: true }
319
+ capabilities: {
320
+ vision: false,
321
+ structuredOutput: true
322
+ }
323
+ }, {
324
+ name: "qwen-vl-plus",
325
+ capabilities: {
326
+ vision: true,
327
+ structuredOutput: true
328
+ }
311
329
  }];
312
330
  const DEFAULT_PROVIDER_CONFIG = {
313
331
  baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1",
@@ -324,22 +342,11 @@ Extraction requirements:
324
342
  1. Extract strictly according to the field names and types defined in the structure
325
343
  2. If the text lacks information for a field, set that field to null
326
344
  3. Do not add fields that do not exist in the structure definition
327
- 4. Use only facts present in the source text; do not infer, guess, or complete missing values from outside knowledge
328
- 5. Normalize values to the target type: numbers as JSON numbers, booleans as true/false, dates and formatted strings exactly as requested by the field format
329
- 6. For repeated or conflicting mentions, prefer the most specific final value in the source text and ignore placeholder values such as N/A, unknown, TBD, or empty strings
330
- 7. Maintain data accuracy and completeness`,
345
+ 4. Maintain data accuracy and completeness`,
331
346
  userTemplate: `Please extract data from the following text:
332
347
  {text}`
333
348
  };
334
- const DEFAULT_EXTRACTION_CONFIG = {
335
- outputDir: ".aiex/extracted",
336
- mode: "pipeline"
337
- };
338
- const DEFAULT_IMAGE_OCR_CONFIG = {
339
- imageConversion: "local",
340
- ocrLanguages: "en-US, zh-Hans",
341
- ocrMinConfidence: 0
342
- };
349
+ const DEFAULT_EXTRACTION_CONFIG = { outputDir: ".aiex/extracted" };
343
350
  const DEFAULT_MINERU_CONFIG = {
344
351
  command: "mineru",
345
352
  args: [
@@ -368,7 +375,6 @@ const DEFAULT_AI_CONFIG = {
368
375
  provider: DEFAULT_PROVIDER_CONFIG,
369
376
  prompt: DEFAULT_PROMPT_CONFIG,
370
377
  extraction: DEFAULT_EXTRACTION_CONFIG,
371
- image: DEFAULT_IMAGE_OCR_CONFIG,
372
378
  pdf: DEFAULT_PDF_CONFIG,
373
379
  webhook: {
374
380
  enabled: false,
@@ -534,8 +540,6 @@ const en = {
534
540
  file: {
535
541
  hashWarning: "Failed to calculate file hash for {{file}}: {{error}}",
536
542
  alreadyProcessed: "File {{file}} (hash: {{hash}}) has already been processed successfully. Skipping.",
537
- visionTranscribed: "Transcribed image text via AI vision model ({{model}})",
538
- visionTranscribeFailed: "Vision model transcription failed for {{model}}, falling back to local OCR",
539
543
  ocrText: "Extracted image text via local OCR (confidence: {{confidence}}%)",
540
544
  pdfFallback: "Fell back to unpdf — {{count}} page(s) extracted",
541
545
  pdfConverted: "Converted PDF via {{name}}, {{count}} page(s)",
@@ -546,12 +550,6 @@ const en = {
546
550
  extractFail: "Extraction failed",
547
551
  extractComplete: "Extraction complete",
548
552
  extractRetry: "API responded with {{code}}, retrying in {{delay}}s ({{attempt}}/{{max}})",
549
- chunking: "Input text ({{length}} tokens) exceeds limit ({{limit}} tokens). Splitting into chunks...",
550
- chunksCount: "Split into {{count}} chunk(s).",
551
- extractingChunk: "Extracting chunk {{current}}/{{total}}...",
552
- extractRetryChunk: "Chunk {{current}}/{{total}} API responded with {{code}}, retrying in {{delay}}s ({{attempt}}/{{max}})",
553
- extractFailChunk: "Extraction failed for chunk {{current}}/{{total}}",
554
- validationFail: "Merged data validation failed",
555
553
  resultSaved: "Result saved: {{path}}",
556
554
  tokenUsage: "Token usage: prompt={{prompt}}, completion={{completion}}, total={{total}}",
557
555
  insertingDb: "Inserting into database...",
@@ -659,10 +657,14 @@ const en = {
659
657
  ai: {
660
658
  apiKeyMissing: "API Key not configured. Please configure AI settings in the web UI.",
661
659
  extractionNotObject: "Extraction result is not an object and cannot be written to Notion.",
662
- noModels: "No AI models configured. Please add at least one model in AI Settings."
660
+ noModels: "No AI models configured. Please add at least one model in AI Settings.",
661
+ noVisionModel: "Image input requires a model with vision capability{{hint}}.",
662
+ noVisionModelContext: "No vision-capable model with sufficient context window (≥{{tokens}} tokens) found{{hint}}.",
663
+ addSuitableModel: " Please add a suitable vision-capable model in AI Settings."
663
664
  },
664
665
  ocr: {
665
666
  platformUnsupported: "Local OCR is only available on macOS or Windows. Current platform: {{platform}}.",
667
+ disabled: "Image OCR fallback is disabled in AI settings.",
666
668
  unavailable: "Local OCR is unavailable. Install optional dependency @napi-rs/system-ocr and approve its native build scripts. {{error}}",
667
669
  noText: "Local OCR did not recognize any text in the image.",
668
670
  lowConfidence: "Local OCR confidence {{confidence}}% is below the configured minimum {{min}}%."
@@ -764,19 +766,26 @@ const en = {
764
766
  models: "Models",
765
767
  addModel: "Add Model",
766
768
  modelName: "Model name (e.g. gpt-4o)",
769
+ structuredOutput: "Structured Output",
770
+ textOnlyOutput: "Text-only Output",
771
+ visionSupported: "Vision Supported",
772
+ visionUnsupported: "Vision Unsupported",
767
773
  subscribe: "Registry",
768
774
  imageInput: "Image Input",
769
775
  imageInputSummary: {
770
- visionModel: "Image text is transcribed via {{model}} before structured extraction.",
771
- ocrNoModel: "No vision model selected. Image text will be read through local OCR.",
772
- ocrLocal: "Image text will be read through local OCR."
776
+ visionModel: "Image files will use your configured vision model first.",
777
+ ocrFallback: "No vision model is configured, and local OCR is unavailable.",
778
+ ocrLocal: "No vision model is configured. Image text will require local OCR on macOS or Windows.",
779
+ ocrAuto: "No vision model is configured. On macOS or Windows, local OCR will be tried automatically for text-heavy images."
773
780
  },
781
+ visionModelConfigured: "Vision model configured",
782
+ noVisionModel: "No vision model",
774
783
  advancedImageSettings: "Advanced image settings",
775
784
  hideAdvancedImageSettings: "Hide advanced image settings",
776
- ocrFallback: "Image input mode",
785
+ ocrFallback: "Local OCR fallback",
777
786
  ocrLanguages: "Languages",
778
787
  ocrMinConfidence: "Minimum confidence",
779
- ocrHint: "Images are converted to text before structured extraction.",
788
+ ocrHint: "Image extraction always prefers a vision model. OCR fallback is only used when no vision model is available.",
780
789
  pdfConversion: "PDF Conversion",
781
790
  converter: "Converter",
782
791
  command: "Command",
@@ -853,10 +862,7 @@ const en = {
853
862
  mineru: "MinerU (mineru)",
854
863
  external: "Custom External Command"
855
864
  },
856
- ocrFallbackOptions: {
857
- vision: "Vision model (fallback to OCR)",
858
- local: "Local OCR only"
859
- }
865
+ ocrFallbackOptions: { localAuto: "Vision model or local OCR" }
860
866
  },
861
867
  prompt: {
862
868
  defaultSystem: `You are a professional data extraction assistant. Your task is to extract structured data from text and return a JSON object based on the data structure definition provided below.
@@ -927,7 +933,7 @@ async function initI18n(lng) {
927
933
  fallbackLng: "en",
928
934
  resources: {
929
935
  "en": { translation: en },
930
- "zh-CN": { translation: await import("./zh-CN-DkillGHx.mjs").then((m) => m.zhCN) }
936
+ "zh-CN": { translation: await import("./zh-CN-wEUNhuHM.mjs").then((m) => m.zhCN) }
931
937
  },
932
938
  interpolation: { escapeValue: false },
933
939
  returnNull: false
@@ -951,6 +957,18 @@ const defaultRuntime = {
951
957
  return await import("@napi-rs/system-ocr");
952
958
  }
953
959
  };
960
+ function imageOcrMode(config) {
961
+ return config?.ocrFallback ?? "localAuto";
962
+ }
963
+ function hasVisionModel(aiConfig, modelOverride) {
964
+ if (modelOverride) return modelOverride.capabilities.vision;
965
+ return aiConfig?.provider.models.some((model) => model.capabilities.vision) ?? true;
966
+ }
967
+ function shouldUseImageOcrFallback(aiConfig, modelOverride, runtime = defaultRuntime) {
968
+ if (hasVisionModel(aiConfig, modelOverride)) return false;
969
+ if (imageOcrMode(aiConfig?.image) === "localAuto") return isLocalOcrPlatform(runtime.platform);
970
+ return isLocalOcrPlatform(runtime.platform);
971
+ }
954
972
  function isLocalOcrPlatform(platform) {
955
973
  return platform === "darwin" || platform === "win32";
956
974
  }
@@ -1491,4 +1509,4 @@ async function collectDoctorDiagnostics(options = {}) {
1491
1509
  }
1492
1510
 
1493
1511
  //#endregion
1494
- export { name as C, doctorDiagnosticsTableRows as D, buildDoctorDiagnostics as E, formatDoctorDiagnosticsJson as O, description as S, version as T, PLACEHOLDER_SCHEMA as _, parseJsonSchema as a, createConfig as b, recognizeImageText as c, getDefaultAIConfig as d, readAIConfig as f, DEFAULT_PROMPT_CONFIG as g, DEFAULT_MINERU_CONFIG as h, JsonSchemaDefinitionSchema as i, initI18n as l, DEFAULT_MINERU_API_CONFIG as m, createMigrationConfig as n, toSnakeCase as o, writeAIConfig as p, generateDrizzleConfig as r, generateDrizzleSchema as s, collectDoctorDiagnostics as t, t as u, PLACEHOLDER_TEXT as v, package_default as w, seedConfig as x, AIConfigSchema as y };
1512
+ export { description as C, buildDoctorDiagnostics as D, version as E, doctorDiagnosticsTableRows as O, seedConfig as S, package_default as T, DEFAULT_PROMPT_CONFIG as _, parseJsonSchema as a, AIConfigSchema as b, recognizeImageText as c, t as d, getDefaultAIConfig as f, DEFAULT_MINERU_CONFIG as g, DEFAULT_MINERU_API_CONFIG as h, JsonSchemaDefinitionSchema as i, formatDoctorDiagnosticsJson as k, shouldUseImageOcrFallback as l, writeAIConfig as m, createMigrationConfig as n, toSnakeCase as o, readAIConfig as p, generateDrizzleConfig as r, generateDrizzleSchema as s, collectDoctorDiagnostics as t, initI18n as u, PLACEHOLDER_SCHEMA as v, name as w, createConfig as x, PLACEHOLDER_TEXT as y };
package/dist/index.d.mts CHANGED
@@ -1,12 +1,7 @@
1
1
  import Conf from "conf";
2
2
  import { ZodError, z } from "zod";
3
- import "@napi-rs/system-ocr";
4
3
 
5
- //#region src/types/config.d.ts
6
- interface AppConfig {
7
- name?: string;
8
- version?: string;
9
- }
4
+ //#region src/core/doctor.d.ts
10
5
  interface DoctorDiagnostics {
11
6
  cli: {
12
7
  name: string;
@@ -53,6 +48,93 @@ interface DoctorDiagnostics {
53
48
  errors: string[];
54
49
  };
55
50
  }
51
+ declare function buildDoctorDiagnostics(input: {
52
+ pkg: {
53
+ name: string;
54
+ version: string;
55
+ };
56
+ executable: string;
57
+ node: string;
58
+ platform: string;
59
+ arch: string;
60
+ shell: string;
61
+ packageManager: string;
62
+ osType: string;
63
+ osRelease: string;
64
+ cwd: string;
65
+ imageOcr: DoctorDiagnostics['imageOcr'];
66
+ configPath: string;
67
+ configStoreKeys: string[];
68
+ project: DoctorDiagnostics['project'];
69
+ }): DoctorDiagnostics;
70
+ declare function formatDoctorDiagnosticsJson(d: DoctorDiagnostics): string;
71
+ declare function doctorDiagnosticsTableRows(d: DoctorDiagnostics): [string, string][];
72
+ //#endregion
73
+ //#region src/config.d.ts
74
+ interface AppConfig {
75
+ name?: string;
76
+ version?: string;
77
+ }
78
+ declare function createConfig(): Conf<AppConfig>;
79
+ //#endregion
80
+ //#region src/core/doctor-collector.d.ts
81
+ interface CollectDoctorDiagnosticsOptions {
82
+ config?: ReturnType<typeof createConfig>;
83
+ }
84
+ declare function collectDoctorDiagnostics(options?: CollectDoctorDiagnosticsOptions): Promise<DoctorDiagnostics>;
85
+ //#endregion
86
+ //#region src/core/schema-sqlite/types.d.ts
87
+ interface ParsedColumn {
88
+ name: string;
89
+ drizzleType: string;
90
+ isPrimary: boolean;
91
+ isAutoIncrement: boolean;
92
+ isNullable: boolean;
93
+ isUnique: boolean;
94
+ defaultValue?: string;
95
+ isForeignKey?: boolean;
96
+ foreignKeyRef?: {
97
+ table: string;
98
+ column: string;
99
+ };
100
+ }
101
+ interface ParsedTable {
102
+ name: string;
103
+ columns: ParsedColumn[];
104
+ }
105
+ interface ParsedRelation {
106
+ fromTable: string;
107
+ fromColumn: string;
108
+ toTable: string;
109
+ toColumn: string;
110
+ name: string;
111
+ }
112
+ interface ParsedReverseRelation {
113
+ type: 'has-one' | 'has-many';
114
+ fromTable: string;
115
+ toTable: string;
116
+ name: string;
117
+ }
118
+ interface ParseResult {
119
+ tables: ParsedTable[];
120
+ relations: ParsedRelation[];
121
+ reverseRelations: ParsedReverseRelation[];
122
+ warnings: string[];
123
+ }
124
+ interface MigrationConfig {
125
+ schemaPath: string;
126
+ drizzleSchemaPath: string;
127
+ migrationsPath: string;
128
+ databasePath: string;
129
+ drizzleConfigPath: string;
130
+ }
131
+ //#endregion
132
+ //#region src/core/schema-sqlite/generator.d.ts
133
+ declare function generateDrizzleSchema(result: ParseResult): string;
134
+ //#endregion
135
+ //#region src/core/schema-sqlite/migrator.d.ts
136
+ declare function createMigrationConfig(cwd: string): MigrationConfig;
137
+ declare function generateDrizzleConfig(): string;
56
138
  //#endregion
57
139
  //#region src/core/schema-sqlite/schemas.d.ts
58
140
 
@@ -246,91 +328,6 @@ interface JsonSchemaProperty {
246
328
  }
247
329
  type JsonSchemaDefinition = z.infer<typeof JsonSchemaDefinitionSchema>;
248
330
  //#endregion
249
- //#region src/types/database.d.ts
250
- interface ParsedColumn {
251
- name: string;
252
- drizzleType: string;
253
- isPrimary: boolean;
254
- isAutoIncrement: boolean;
255
- isNullable: boolean;
256
- isUnique: boolean;
257
- defaultValue?: string;
258
- isForeignKey?: boolean;
259
- foreignKeyRef?: {
260
- table: string;
261
- column: string;
262
- };
263
- }
264
- interface ParsedTable {
265
- name: string;
266
- columns: ParsedColumn[];
267
- }
268
- interface ParsedRelation {
269
- fromTable: string;
270
- fromColumn: string;
271
- toTable: string;
272
- toColumn: string;
273
- name: string;
274
- }
275
- interface ParsedReverseRelation {
276
- type: 'has-one' | 'has-many';
277
- fromTable: string;
278
- toTable: string;
279
- name: string;
280
- }
281
- interface ParseResult {
282
- tables: ParsedTable[];
283
- relations: ParsedRelation[];
284
- reverseRelations: ParsedReverseRelation[];
285
- warnings: string[];
286
- }
287
- interface MigrationConfig {
288
- schemaPath: string;
289
- drizzleSchemaPath: string;
290
- migrationsPath: string;
291
- databasePath: string;
292
- drizzleConfigPath: string;
293
- }
294
- //#endregion
295
- //#region src/core/doctor.d.ts
296
- declare function buildDoctorDiagnostics(input: {
297
- pkg: {
298
- name: string;
299
- version: string;
300
- };
301
- executable: string;
302
- node: string;
303
- platform: string;
304
- arch: string;
305
- shell: string;
306
- packageManager: string;
307
- osType: string;
308
- osRelease: string;
309
- cwd: string;
310
- imageOcr: DoctorDiagnostics['imageOcr'];
311
- configPath: string;
312
- configStoreKeys: string[];
313
- project: DoctorDiagnostics['project'];
314
- }): DoctorDiagnostics;
315
- declare function formatDoctorDiagnosticsJson(d: DoctorDiagnostics): string;
316
- declare function doctorDiagnosticsTableRows(d: DoctorDiagnostics): [string, string][];
317
- //#endregion
318
- //#region src/config.d.ts
319
- declare function createConfig(): Conf<AppConfig>;
320
- //#endregion
321
- //#region src/core/doctor-collector.d.ts
322
- interface CollectDoctorDiagnosticsOptions {
323
- config?: ReturnType<typeof createConfig>;
324
- }
325
- declare function collectDoctorDiagnostics(options?: CollectDoctorDiagnosticsOptions): Promise<DoctorDiagnostics>;
326
- //#endregion
327
- //#region src/core/schema-sqlite/generator.d.ts
328
- declare function generateDrizzleSchema(result: ParseResult): string;
329
- //#endregion
330
- //#region src/core/schema-sqlite/migrator.d.ts
331
- declare function createMigrationConfig(cwd: string): MigrationConfig;
332
- declare function generateDrizzleConfig(): string;
333
- //#endregion
334
331
  //#region src/core/schema-sqlite/parser.d.ts
335
332
  declare function parseJsonSchema(schema: JsonSchemaDefinition): ParseResult;
336
333
  //#endregion
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { D as doctorDiagnosticsTableRows, E as buildDoctorDiagnostics, O as formatDoctorDiagnosticsJson, a as parseJsonSchema, i as JsonSchemaDefinitionSchema, n as createMigrationConfig, r as generateDrizzleConfig, s as generateDrizzleSchema, t as collectDoctorDiagnostics } from "./doctor-collector-BpqhXNcO.mjs";
1
+ import { D as buildDoctorDiagnostics, O as doctorDiagnosticsTableRows, a as parseJsonSchema, i as JsonSchemaDefinitionSchema, k as formatDoctorDiagnosticsJson, n as createMigrationConfig, r as generateDrizzleConfig, s as generateDrizzleSchema, t as collectDoctorDiagnostics } from "./doctor-collector-CGo5dgHm.mjs";
2
2
 
3
3
  export { JsonSchemaDefinitionSchema, buildDoctorDiagnostics, collectDoctorDiagnostics, createMigrationConfig, doctorDiagnosticsTableRows, formatDoctorDiagnosticsJson, generateDrizzleConfig, generateDrizzleSchema, parseJsonSchema };