@amirdaraee/namewise 0.7.1 → 0.8.0
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/CHANGELOG.md +21 -0
- package/README.md +49 -4
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +6 -0
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +11 -0
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/rename.d.ts.map +1 -1
- package/dist/cli/rename.js +3 -2
- package/dist/cli/rename.js.map +1 -1
- package/dist/cli/watch.js +1 -1
- package/dist/cli/watch.js.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/parsers/factory.d.ts.map +1 -1
- package/dist/parsers/factory.js +7 -2
- package/dist/parsers/factory.js.map +1 -1
- package/dist/parsers/image-parser.d.ts +6 -0
- package/dist/parsers/image-parser.d.ts.map +1 -0
- package/dist/parsers/image-parser.js +29 -0
- package/dist/parsers/image-parser.js.map +1 -0
- package/dist/services/claude-service.d.ts +1 -1
- package/dist/services/claude-service.d.ts.map +1 -1
- package/dist/services/claude-service.js +14 -33
- package/dist/services/claude-service.js.map +1 -1
- package/dist/services/file-renamer.d.ts.map +1 -1
- package/dist/services/file-renamer.js +47 -21
- package/dist/services/file-renamer.js.map +1 -1
- package/dist/services/lmstudio-service.d.ts +1 -2
- package/dist/services/lmstudio-service.d.ts.map +1 -1
- package/dist/services/lmstudio-service.js +26 -29
- package/dist/services/lmstudio-service.js.map +1 -1
- package/dist/services/ollama-service.d.ts +1 -3
- package/dist/services/ollama-service.d.ts.map +1 -1
- package/dist/services/ollama-service.js +34 -84
- package/dist/services/ollama-service.js.map +1 -1
- package/dist/services/openai-service.d.ts +1 -1
- package/dist/services/openai-service.d.ts.map +1 -1
- package/dist/services/openai-service.js +13 -37
- package/dist/services/openai-service.js.map +1 -1
- package/dist/types/index.d.ts +3 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/ai-prompts.d.ts +1 -0
- package/dist/utils/ai-prompts.d.ts.map +1 -1
- package/dist/utils/ai-prompts.js +3 -2
- package/dist/utils/ai-prompts.js.map +1 -1
- package/dist/utils/config-loader.d.ts +1 -0
- package/dist/utils/config-loader.d.ts.map +1 -1
- package/dist/utils/config-loader.js.map +1 -1
- package/dist/utils/image-compressor.d.ts +13 -0
- package/dist/utils/image-compressor.d.ts.map +1 -0
- package/dist/utils/image-compressor.js +52 -0
- package/dist/utils/image-compressor.js.map +1 -0
- package/dist/utils/pdf-to-image.d.ts +0 -1
- package/dist/utils/pdf-to-image.d.ts.map +1 -1
- package/dist/utils/pdf-to-image.js +6 -45
- package/dist/utils/pdf-to-image.js.map +1 -1
- package/package.json +4 -1
|
@@ -9,26 +9,23 @@ export class ClaudeService {
|
|
|
9
9
|
this.client = new Anthropic({ apiKey });
|
|
10
10
|
this.model = model ?? 'claude-sonnet-4-5-20250929';
|
|
11
11
|
}
|
|
12
|
-
async generateFileName(content, originalName, namingConvention = 'kebab-case', category = 'general', fileInfo, language) {
|
|
12
|
+
async generateFileName(content, originalName, namingConvention = 'kebab-case', category = 'general', fileInfo, language, context, imageData) {
|
|
13
13
|
const convention = namingConvention;
|
|
14
14
|
const fileCategory = category;
|
|
15
|
-
// Check if this is a scanned PDF image
|
|
16
|
-
const isScannedPDF = content.startsWith('[SCANNED_PDF_IMAGE]:');
|
|
17
15
|
try {
|
|
18
16
|
let response;
|
|
19
|
-
if (
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (!imageBase64.startsWith('data:image/') || !imageBase64.includes(',')) {
|
|
23
|
-
throw new Error('Invalid scanned PDF image data format');
|
|
17
|
+
if (imageData) {
|
|
18
|
+
if (!imageData.startsWith('data:image/') || !imageData.includes(',')) {
|
|
19
|
+
throw new Error('Invalid image data format');
|
|
24
20
|
}
|
|
25
21
|
const prompt = buildFileNamePrompt({
|
|
26
|
-
content: '
|
|
22
|
+
content: 'Analyze this image and generate an appropriate filename based on what you see.',
|
|
27
23
|
originalName,
|
|
28
24
|
namingConvention: convention,
|
|
29
25
|
category: fileCategory,
|
|
30
26
|
fileInfo,
|
|
31
|
-
language
|
|
27
|
+
language,
|
|
28
|
+
context
|
|
32
29
|
});
|
|
33
30
|
response = await this.client.messages.create({
|
|
34
31
|
model: this.model,
|
|
@@ -37,16 +34,13 @@ export class ClaudeService {
|
|
|
37
34
|
{
|
|
38
35
|
role: 'user',
|
|
39
36
|
content: [
|
|
40
|
-
{
|
|
41
|
-
type: 'text',
|
|
42
|
-
text: prompt
|
|
43
|
-
},
|
|
37
|
+
{ type: 'text', text: prompt },
|
|
44
38
|
{
|
|
45
39
|
type: 'image',
|
|
46
40
|
source: {
|
|
47
41
|
type: 'base64',
|
|
48
|
-
media_type:
|
|
49
|
-
data:
|
|
42
|
+
media_type: imageData.startsWith('data:image/png') ? 'image/png' : 'image/jpeg',
|
|
43
|
+
data: imageData.split(',')[1]
|
|
50
44
|
}
|
|
51
45
|
}
|
|
52
46
|
]
|
|
@@ -55,33 +49,26 @@ export class ClaudeService {
|
|
|
55
49
|
});
|
|
56
50
|
}
|
|
57
51
|
else {
|
|
58
|
-
// Standard text processing
|
|
59
52
|
const prompt = buildFileNamePrompt({
|
|
60
53
|
content,
|
|
61
54
|
originalName,
|
|
62
55
|
namingConvention: convention,
|
|
63
56
|
category: fileCategory,
|
|
64
57
|
fileInfo,
|
|
65
|
-
language
|
|
58
|
+
language,
|
|
59
|
+
context
|
|
66
60
|
});
|
|
67
61
|
response = await this.client.messages.create({
|
|
68
62
|
model: this.model,
|
|
69
63
|
max_tokens: 100,
|
|
70
|
-
messages: [
|
|
71
|
-
{
|
|
72
|
-
role: 'user',
|
|
73
|
-
content: prompt
|
|
74
|
-
}
|
|
75
|
-
]
|
|
64
|
+
messages: [{ role: 'user', content: prompt }]
|
|
76
65
|
});
|
|
77
66
|
}
|
|
78
67
|
const suggestedName = response.content[0].type === 'text'
|
|
79
68
|
? response.content[0].text.trim()
|
|
80
69
|
: 'untitled-document';
|
|
81
|
-
// Apply naming convention and clean the suggested name
|
|
82
|
-
const name = this.sanitizeFileName(suggestedName, convention);
|
|
83
70
|
return {
|
|
84
|
-
name,
|
|
71
|
+
name: this.sanitizeFileName(suggestedName, convention),
|
|
85
72
|
inputTokens: response.usage?.input_tokens,
|
|
86
73
|
outputTokens: response.usage?.output_tokens
|
|
87
74
|
};
|
|
@@ -92,20 +79,14 @@ export class ClaudeService {
|
|
|
92
79
|
}
|
|
93
80
|
}
|
|
94
81
|
sanitizeFileName(name, convention) {
|
|
95
|
-
// Remove any potential file extensions from the suggestion
|
|
96
82
|
const nameWithoutExt = name.replace(/\.[^/.]+$/, '');
|
|
97
|
-
// Strip Windows-illegal characters before applying the naming convention
|
|
98
83
|
const safeForWindows = stripWindowsIllegalChars(nameWithoutExt);
|
|
99
|
-
// Apply the naming convention
|
|
100
84
|
let cleaned = applyNamingConvention(safeForWindows, convention);
|
|
101
|
-
// Ensure it's not empty and not too long
|
|
102
85
|
if (!cleaned) {
|
|
103
86
|
cleaned = applyNamingConvention('untitled document', convention);
|
|
104
87
|
}
|
|
105
88
|
else if (cleaned.length > 100) {
|
|
106
|
-
// Truncate while preserving naming convention structure
|
|
107
89
|
cleaned = cleaned.substring(0, 100);
|
|
108
|
-
// Clean up any broken separators at the end
|
|
109
90
|
if (convention === 'kebab-case') {
|
|
110
91
|
cleaned = cleaned.replace(/-[^-]*$/, '');
|
|
111
92
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-service.js","sourceRoot":"","sources":["../../src/services/claude-service.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAE1C,OAAO,EAAE,qBAAqB,EAAE,wBAAwB,EAAoB,MAAM,gCAAgC,CAAC;AAEnH,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAE7D,MAAM,OAAO,aAAa;IACxB,IAAI,GAAG,QAAQ,CAAC;IACR,MAAM,CAAY;IAClB,KAAK,CAAS;IAEtB,YAAY,MAAc,EAAE,KAAc;QACxC,IAAI,CAAC,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK,GAAG,KAAK,IAAI,4BAA4B,CAAC;IACrD,CAAC;IAED,KAAK,CAAC,gBAAgB,
|
|
1
|
+
{"version":3,"file":"claude-service.js","sourceRoot":"","sources":["../../src/services/claude-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-renamer.d.ts","sourceRoot":"","sources":["../../src/services/file-renamer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAgB,UAAU,EAAgB,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAClH,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"file-renamer.d.ts","sourceRoot":"","sources":["../../src/services/file-renamer.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAgB,UAAU,EAAgB,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAClH,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAO9D,qBAAa,WAAW;IAEpB,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,SAAS;IACjB,OAAO,CAAC,MAAM;gBAFN,aAAa,EAAE,qBAAqB,EACpC,SAAS,EAAE,UAAU,EACrB,MAAM,EAAE,MAAM;IAGlB,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,mBAAmB,CAAC;YA8EpD,UAAU;YA2EV,qBAAqB;YAiCrB,eAAe;CAuB9B"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { promises as fs } from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { categorizeFile, applyTemplate } from '../utils/file-templates.js';
|
|
4
|
+
const IMAGE_EXTENSIONS = new Set([
|
|
5
|
+
'.jpg', '.jpeg', '.png', '.gif', '.bmp', '.tiff', '.heic', '.webp'
|
|
6
|
+
]);
|
|
4
7
|
export class FileRenamer {
|
|
5
8
|
parserFactory;
|
|
6
9
|
aiService;
|
|
@@ -80,54 +83,53 @@ export class FileRenamer {
|
|
|
80
83
|
}
|
|
81
84
|
return {
|
|
82
85
|
results,
|
|
83
|
-
tokenUsage: {
|
|
84
|
-
inputTokens: totalInputTokens,
|
|
85
|
-
outputTokens: totalOutputTokens
|
|
86
|
-
}
|
|
86
|
+
tokenUsage: { inputTokens: totalInputTokens, outputTokens: totalOutputTokens }
|
|
87
87
|
};
|
|
88
88
|
}
|
|
89
89
|
async renameFile(file) {
|
|
90
|
-
// Check file size
|
|
91
90
|
if (file.size > this.config.maxFileSize) {
|
|
92
91
|
throw new Error(`File size (${Math.round(file.size / 1024 / 1024)}MB) exceeds maximum allowed size (${Math.round(this.config.maxFileSize / 1024 / 1024)}MB)`);
|
|
93
92
|
}
|
|
94
|
-
// Get appropriate parser
|
|
95
93
|
const parser = this.parserFactory.getParser(file.path);
|
|
96
94
|
if (!parser) {
|
|
97
95
|
throw new Error(`No parser available for file type: ${file.extension}`);
|
|
98
96
|
}
|
|
99
|
-
// Extract content and metadata
|
|
100
97
|
const parseResult = await parser.parse(file.path);
|
|
101
|
-
const content = parseResult
|
|
102
|
-
|
|
98
|
+
const { content, imageData } = parseResult;
|
|
99
|
+
// Require content unless this is an image file (imageData replaces content)
|
|
100
|
+
if (!imageData && (!content || content.trim().length === 0)) {
|
|
103
101
|
throw new Error('No content could be extracted from the file');
|
|
104
102
|
}
|
|
105
|
-
// Update file info with extracted document metadata
|
|
106
103
|
file.documentMetadata = parseResult.metadata;
|
|
107
|
-
// Determine file category (use configured category or auto-categorize)
|
|
108
104
|
const fileCategory = this.config.templateOptions.category === 'auto'
|
|
109
105
|
? categorizeFile(file.path, content, file)
|
|
110
106
|
: this.config.templateOptions.category;
|
|
111
|
-
// Generate core filename using AI (or metadata if --no-ai)
|
|
112
107
|
let aiResult;
|
|
113
108
|
if (this.config.noAi) {
|
|
114
|
-
aiResult = { name: this.buildNameFromMetadata(file), inputTokens: undefined, outputTokens: undefined };
|
|
109
|
+
aiResult = { name: await this.buildNameFromMetadata(file), inputTokens: undefined, outputTokens: undefined };
|
|
110
|
+
}
|
|
111
|
+
else if (imageData) {
|
|
112
|
+
// Image file — attempt vision API; skip with warning on any failure
|
|
113
|
+
try {
|
|
114
|
+
aiResult = await this.aiService.generateFileName(content, file.name, this.config.namingConvention, fileCategory, file, this.config.language, this.config.context, imageData);
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
118
|
+
console.warn(`\n⚠️ Skipped ${file.name} — model does not support vision (${msg})`);
|
|
119
|
+
throw new Error(`Vision not supported: ${msg}`);
|
|
120
|
+
}
|
|
115
121
|
}
|
|
116
122
|
else {
|
|
117
|
-
aiResult = await this.aiService.generateFileName(content, file.name, this.config.namingConvention, fileCategory, file, this.config.language);
|
|
123
|
+
aiResult = await this.aiService.generateFileName(content, file.name, this.config.namingConvention, fileCategory, file, this.config.language, this.config.context);
|
|
118
124
|
}
|
|
119
125
|
if (!aiResult.name || aiResult.name.trim().length === 0) {
|
|
120
126
|
throw new Error('Failed to generate a filename');
|
|
121
127
|
}
|
|
122
128
|
const coreFileName = aiResult.name;
|
|
123
|
-
// Apply template to include personal info, dates, etc.
|
|
124
129
|
const templatedName = applyTemplate(coreFileName, fileCategory, this.config.templateOptions, this.config.namingConvention, file);
|
|
125
|
-
// Create new filename with original extension
|
|
126
130
|
const newFileName = `${templatedName}${file.extension}`;
|
|
127
131
|
const newPath = path.join(path.dirname(file.path), newFileName);
|
|
128
|
-
// Resolve final path, auto-numbering if target already exists
|
|
129
132
|
const finalPath = newPath === file.path ? newPath : await this.resolveConflict(newPath);
|
|
130
|
-
// Perform the rename (or simulate if dry run)
|
|
131
133
|
if (!this.config.dryRun && finalPath !== file.path) {
|
|
132
134
|
await fs.rename(file.path, finalPath);
|
|
133
135
|
}
|
|
@@ -142,11 +144,35 @@ export class FileRenamer {
|
|
|
142
144
|
outputTokens: aiResult.outputTokens
|
|
143
145
|
};
|
|
144
146
|
}
|
|
145
|
-
buildNameFromMetadata(file) {
|
|
147
|
+
async buildNameFromMetadata(file) {
|
|
148
|
+
// Image files: try EXIF metadata first
|
|
149
|
+
if (IMAGE_EXTENSIONS.has(file.extension.toLowerCase())) {
|
|
150
|
+
try {
|
|
151
|
+
const exifr = (await import('exifr')).default;
|
|
152
|
+
const exif = await exifr.parse(file.path, {
|
|
153
|
+
pick: ['DateTimeOriginal', 'ImageDescription', 'UserComment']
|
|
154
|
+
});
|
|
155
|
+
if (exif?.ImageDescription?.trim())
|
|
156
|
+
return exif.ImageDescription.trim();
|
|
157
|
+
if (exif?.UserComment?.trim())
|
|
158
|
+
return exif.UserComment.trim();
|
|
159
|
+
if (exif?.DateTimeOriginal) {
|
|
160
|
+
const d = new Date(exif.DateTimeOriginal);
|
|
161
|
+
const y = d.getFullYear();
|
|
162
|
+
const m = String(d.getMonth() + 1).padStart(2, '0');
|
|
163
|
+
const day = String(d.getDate()).padStart(2, '0');
|
|
164
|
+
return `photo-${y}-${m}-${day}`;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
// Fall through to filename stem
|
|
169
|
+
}
|
|
170
|
+
return path.basename(file.name, file.extension).replace(/[-_]/g, ' ');
|
|
171
|
+
}
|
|
172
|
+
// Document files: use extracted metadata
|
|
146
173
|
const meta = file.documentMetadata;
|
|
147
|
-
if (meta?.title?.trim())
|
|
174
|
+
if (meta?.title?.trim())
|
|
148
175
|
return meta.title.trim();
|
|
149
|
-
}
|
|
150
176
|
if (meta?.author) {
|
|
151
177
|
const year = meta.creationDate ? meta.creationDate.getFullYear().toString() : '';
|
|
152
178
|
return [meta.author, year].filter(Boolean).join(' ');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-renamer.js","sourceRoot":"","sources":["../../src/services/file-renamer.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"file-renamer.js","sourceRoot":"","sources":["../../src/services/file-renamer.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,8 +5,7 @@ export declare class LMStudioService implements AIProvider {
|
|
|
5
5
|
private model;
|
|
6
6
|
constructor(baseUrl?: string, model?: string);
|
|
7
7
|
private validateLocalUrl;
|
|
8
|
-
generateFileName(content: string, originalName: string, namingConvention?: string, category?: string, fileInfo?: FileInfo, language?: string): Promise<AINameResult>;
|
|
9
|
-
private buildPrompt;
|
|
8
|
+
generateFileName(content: string, originalName: string, namingConvention?: string, category?: string, fileInfo?: FileInfo, language?: string, context?: string, imageData?: string): Promise<AINameResult>;
|
|
10
9
|
private sanitizeFilename;
|
|
11
10
|
private makeRequest;
|
|
12
11
|
isAvailable(): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lmstudio-service.d.ts","sourceRoot":"","sources":["../../src/services/lmstudio-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAgCvE,qBAAa,eAAgB,YAAW,UAAU;IAChD,IAAI,SAAc;IAClB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAS;gBAGpB,OAAO,SAA0B,EACjC,KAAK,SAAgB;IAMvB,OAAO,CAAC,gBAAgB;IAelB,gBAAgB,CACpB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,gBAAgB,SAAe,EAC/B,QAAQ,SAAY,EACpB,QAAQ,CAAC,EAAE,QAAQ,EACnB,QAAQ,CAAC,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"lmstudio-service.d.ts","sourceRoot":"","sources":["../../src/services/lmstudio-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAgCvE,qBAAa,eAAgB,YAAW,UAAU;IAChD,IAAI,SAAc;IAClB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAS;gBAGpB,OAAO,SAA0B,EACjC,KAAK,SAAgB;IAMvB,OAAO,CAAC,gBAAgB;IAelB,gBAAgB,CACpB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,gBAAgB,SAAe,EAC/B,QAAQ,SAAY,EACpB,QAAQ,CAAC,EAAE,QAAQ,EACnB,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,CAAC;IAqDxB,OAAO,CAAC,gBAAgB;YAUV,WAAW;IAqBnB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAU/B,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;CAWtC"}
|
|
@@ -22,27 +22,36 @@ export class LMStudioService {
|
|
|
22
22
|
}
|
|
23
23
|
return url;
|
|
24
24
|
}
|
|
25
|
-
async generateFileName(content, originalName, namingConvention = 'kebab-case', category = 'general', fileInfo, language) {
|
|
25
|
+
async generateFileName(content, originalName, namingConvention = 'kebab-case', category = 'general', fileInfo, language, context, imageData) {
|
|
26
26
|
try {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (isScannedPDF) {
|
|
30
|
-
// LM Studio has limited vision support, so we'll fall back to using the original filename
|
|
31
|
-
console.log('Scanned PDF detected but LMStudio has limited vision support. Using original filename.');
|
|
32
|
-
return { name: this.sanitizeFilename(originalName), inputTokens: undefined, outputTokens: undefined };
|
|
27
|
+
if (imageData && (!imageData.startsWith('data:image/') || !imageData.includes(','))) {
|
|
28
|
+
throw new Error('Invalid image data format');
|
|
33
29
|
}
|
|
34
|
-
const prompt =
|
|
30
|
+
const prompt = buildFileNamePrompt({
|
|
31
|
+
content: imageData
|
|
32
|
+
? 'Analyze this image and generate an appropriate filename based on what you see.'
|
|
33
|
+
: content,
|
|
34
|
+
originalName,
|
|
35
|
+
namingConvention: namingConvention,
|
|
36
|
+
category: category,
|
|
37
|
+
fileInfo,
|
|
38
|
+
language,
|
|
39
|
+
context
|
|
40
|
+
});
|
|
41
|
+
const userMessage = imageData
|
|
42
|
+
? {
|
|
43
|
+
role: 'user',
|
|
44
|
+
content: [
|
|
45
|
+
{ type: 'text', text: prompt },
|
|
46
|
+
{ type: 'image_url', image_url: { url: imageData } }
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
: { role: 'user', content: prompt };
|
|
35
50
|
const response = await this.makeRequest('/v1/chat/completions', {
|
|
36
51
|
model: this.model,
|
|
37
52
|
messages: [
|
|
38
|
-
{
|
|
39
|
-
|
|
40
|
-
content: AI_SYSTEM_PROMPT
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
role: 'user',
|
|
44
|
-
content: prompt
|
|
45
|
-
}
|
|
53
|
+
{ role: 'system', content: AI_SYSTEM_PROMPT },
|
|
54
|
+
userMessage
|
|
46
55
|
],
|
|
47
56
|
temperature: 0.3,
|
|
48
57
|
max_tokens: 100,
|
|
@@ -55,25 +64,13 @@ export class LMStudioService {
|
|
|
55
64
|
outputTokens: undefined
|
|
56
65
|
};
|
|
57
66
|
}
|
|
58
|
-
|
|
59
|
-
throw new Error('No response content from LMStudio');
|
|
60
|
-
}
|
|
67
|
+
throw new Error('No response content from LMStudio');
|
|
61
68
|
}
|
|
62
69
|
catch (error) {
|
|
63
70
|
console.error('LMStudio API error:', error);
|
|
64
71
|
throw new Error(`LMStudio service failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
65
72
|
}
|
|
66
73
|
}
|
|
67
|
-
buildPrompt(content, originalName, namingConvention, category, fileInfo, language) {
|
|
68
|
-
return buildFileNamePrompt({
|
|
69
|
-
content,
|
|
70
|
-
originalName,
|
|
71
|
-
namingConvention: namingConvention,
|
|
72
|
-
category: category,
|
|
73
|
-
fileInfo,
|
|
74
|
-
language
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
74
|
sanitizeFilename(filename) {
|
|
78
75
|
return filename
|
|
79
76
|
.trim()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lmstudio-service.js","sourceRoot":"","sources":["../../src/services/lmstudio-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AA+B/E,MAAM,OAAO,eAAe;IAC1B,IAAI,GAAG,UAAU,CAAC;IACV,OAAO,CAAS;IAChB,KAAK,CAAS;IAEtB,YACE,OAAO,GAAG,uBAAuB,EACjC,KAAK,GAAG,aAAa;QAErB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAC9C,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAEO,gBAAgB,CAAC,GAAW;QAClC,IAAI,MAAW,CAAC;QAChB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QACxB,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,8BAA8B,GAAG,EAAE,CAAC,CAAC;QACvD,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC/C,MAAM,OAAO,GAAG,QAAQ,KAAK,WAAW,IAAI,QAAQ,KAAK,WAAW,IAAI,QAAQ,KAAK,KAAK,IAAI,QAAQ,KAAK,OAAO,CAAC;QACnH,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,mDAAmD,QAAQ,GAAG,CAAC,CAAC;QAClF,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,KAAK,CAAC,gBAAgB,CACpB,OAAe,EACf,YAAoB,EACpB,gBAAgB,GAAG,YAAY,EAC/B,QAAQ,GAAG,SAAS,EACpB,QAAmB,EACnB,QAAiB;
|
|
1
|
+
{"version":3,"file":"lmstudio-service.js","sourceRoot":"","sources":["../../src/services/lmstudio-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,9 +5,7 @@ export declare class OllamaService implements AIProvider {
|
|
|
5
5
|
private model;
|
|
6
6
|
constructor(baseUrl?: string, model?: string);
|
|
7
7
|
private validateLocalUrl;
|
|
8
|
-
generateFileName(content: string, originalName: string, namingConvention?: string, category?: string, fileInfo?: FileInfo, language?: string): Promise<AINameResult>;
|
|
9
|
-
private buildPrompt;
|
|
10
|
-
private getVisionModel;
|
|
8
|
+
generateFileName(content: string, originalName: string, namingConvention?: string, category?: string, fileInfo?: FileInfo, language?: string, context?: string, imageData?: string): Promise<AINameResult>;
|
|
11
9
|
private sanitizeFilename;
|
|
12
10
|
private makeRequest;
|
|
13
11
|
isAvailable(): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ollama-service.d.ts","sourceRoot":"","sources":["../../src/services/ollama-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"ollama-service.d.ts","sourceRoot":"","sources":["../../src/services/ollama-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAkBvE,qBAAa,aAAc,YAAW,UAAU;IAC9C,IAAI,SAAY;IAChB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAS;gBAEV,OAAO,SAA2B,EAAE,KAAK,SAAa;IAKlE,OAAO,CAAC,gBAAgB;IAelB,gBAAgB,CACpB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,gBAAgB,SAAe,EAC/B,QAAQ,SAAY,EACpB,QAAQ,CAAC,EAAE,QAAQ,EACnB,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,YAAY,CAAC;IAyCxB,OAAO,CAAC,gBAAgB;YAUV,WAAW;IAgBnB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAS/B,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;CAUtC"}
|
|
@@ -22,114 +22,65 @@ export class OllamaService {
|
|
|
22
22
|
}
|
|
23
23
|
return url;
|
|
24
24
|
}
|
|
25
|
-
async generateFileName(content, originalName, namingConvention = 'kebab-case', category = 'general', fileInfo, language) {
|
|
25
|
+
async generateFileName(content, originalName, namingConvention = 'kebab-case', category = 'general', fileInfo, language, context, imageData) {
|
|
26
26
|
try {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
let response;
|
|
30
|
-
if (isScannedPDF) {
|
|
31
|
-
// Extract base64 image data and use a vision model
|
|
32
|
-
const imageBase64 = content.replace('[SCANNED_PDF_IMAGE]:', '');
|
|
33
|
-
const imageData = imageBase64.split(',')[1]; // Remove data:image/format;base64, prefix
|
|
34
|
-
const prompt = this.buildPrompt('This is a scanned PDF document converted to an image. Please analyze the image and extract the main content to generate an appropriate filename.', originalName, namingConvention, category, fileInfo, language);
|
|
35
|
-
// Use LLaVA model for vision capabilities
|
|
36
|
-
const visionModel = this.getVisionModel();
|
|
37
|
-
response = await this.makeRequest('/api/chat', {
|
|
38
|
-
model: visionModel,
|
|
39
|
-
messages: [
|
|
40
|
-
{
|
|
41
|
-
role: 'system',
|
|
42
|
-
content: AI_SYSTEM_PROMPT
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
role: 'user',
|
|
46
|
-
content: prompt,
|
|
47
|
-
images: [imageData]
|
|
48
|
-
}
|
|
49
|
-
],
|
|
50
|
-
stream: false
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
// Standard text processing
|
|
55
|
-
const prompt = this.buildPrompt(content, originalName, namingConvention, category, fileInfo, language);
|
|
56
|
-
response = await this.makeRequest('/api/chat', {
|
|
57
|
-
model: this.model,
|
|
58
|
-
messages: [
|
|
59
|
-
{
|
|
60
|
-
role: 'system',
|
|
61
|
-
content: AI_SYSTEM_PROMPT
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
role: 'user',
|
|
65
|
-
content: prompt
|
|
66
|
-
}
|
|
67
|
-
],
|
|
68
|
-
stream: false
|
|
69
|
-
});
|
|
27
|
+
if (imageData && (!imageData.startsWith('data:image/') || !imageData.includes(','))) {
|
|
28
|
+
throw new Error('Invalid image data format');
|
|
70
29
|
}
|
|
30
|
+
const prompt = buildFileNamePrompt({
|
|
31
|
+
content: imageData
|
|
32
|
+
? 'Analyze this image and generate an appropriate filename based on what you see.'
|
|
33
|
+
: content,
|
|
34
|
+
originalName,
|
|
35
|
+
namingConvention: namingConvention,
|
|
36
|
+
category: category,
|
|
37
|
+
fileInfo,
|
|
38
|
+
language,
|
|
39
|
+
context
|
|
40
|
+
});
|
|
41
|
+
const userMessage = imageData
|
|
42
|
+
? { role: 'user', content: prompt, images: [imageData.split(',')[1]] }
|
|
43
|
+
: { role: 'user', content: prompt };
|
|
44
|
+
const response = await this.makeRequest('/api/chat', {
|
|
45
|
+
model: this.model,
|
|
46
|
+
messages: [
|
|
47
|
+
{ role: 'system', content: AI_SYSTEM_PROMPT },
|
|
48
|
+
userMessage
|
|
49
|
+
],
|
|
50
|
+
stream: false
|
|
51
|
+
});
|
|
71
52
|
if (response.message?.content) {
|
|
72
|
-
return {
|
|
73
|
-
name: this.sanitizeFilename(response.message.content),
|
|
74
|
-
inputTokens: undefined,
|
|
75
|
-
outputTokens: undefined
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
throw new Error('No response content from Ollama');
|
|
53
|
+
return { name: this.sanitizeFilename(response.message.content), inputTokens: undefined, outputTokens: undefined };
|
|
80
54
|
}
|
|
55
|
+
throw new Error('No response content from Ollama');
|
|
81
56
|
}
|
|
82
57
|
catch (error) {
|
|
83
58
|
console.error('Ollama API error:', error);
|
|
84
59
|
throw new Error(`Ollama service failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
85
60
|
}
|
|
86
61
|
}
|
|
87
|
-
buildPrompt(content, originalName, namingConvention, category, fileInfo, language) {
|
|
88
|
-
return buildFileNamePrompt({
|
|
89
|
-
content,
|
|
90
|
-
originalName,
|
|
91
|
-
namingConvention: namingConvention,
|
|
92
|
-
category: category,
|
|
93
|
-
fileInfo,
|
|
94
|
-
language
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
getVisionModel() {
|
|
98
|
-
// Try to use a vision-capable model, fallback to default if not specified
|
|
99
|
-
const visionModels = ['llava', 'llava:7b', 'llava:13b', 'llava:34b', 'llama3.2-vision', 'qwen2-vl'];
|
|
100
|
-
// If the current model is already a vision model, use it
|
|
101
|
-
if (visionModels.some(vm => this.model.toLowerCase().includes(vm.split(':')[0]))) {
|
|
102
|
-
return this.model;
|
|
103
|
-
}
|
|
104
|
-
// Otherwise, default to llava (most common vision model in Ollama)
|
|
105
|
-
return 'llava';
|
|
106
|
-
}
|
|
107
62
|
sanitizeFilename(filename) {
|
|
108
63
|
return filename
|
|
109
64
|
.trim()
|
|
110
|
-
.replace(/^["']|["']$/g, '')
|
|
111
|
-
.replace(/\.(txt|pdf|docx?|xlsx?|md|rtf)$/i, '')
|
|
112
|
-
.replace(/[<>:"/\\|?*]/g, '-')
|
|
113
|
-
.replace(/\s+/g, '-')
|
|
65
|
+
.replace(/^["']|["']$/g, '')
|
|
66
|
+
.replace(/\.(txt|pdf|docx?|xlsx?|md|rtf)$/i, '')
|
|
67
|
+
.replace(/[<>:"/\\|?*]/g, '-')
|
|
68
|
+
.replace(/\s+/g, '-')
|
|
114
69
|
.toLowerCase();
|
|
115
70
|
}
|
|
116
71
|
async makeRequest(endpoint, payload) {
|
|
117
72
|
const url = `${this.baseUrl}${endpoint}`;
|
|
118
73
|
const response = await fetch(url, {
|
|
119
74
|
method: 'POST',
|
|
120
|
-
headers: {
|
|
121
|
-
|
|
122
|
-
},
|
|
123
|
-
body: JSON.stringify(payload),
|
|
75
|
+
headers: { 'Content-Type': 'application/json' },
|
|
76
|
+
body: JSON.stringify(payload)
|
|
124
77
|
});
|
|
125
78
|
if (!response.ok) {
|
|
126
79
|
const errorText = await response.text();
|
|
127
80
|
throw new Error(`Ollama API request failed: ${response.status} ${response.statusText} - ${errorText}`);
|
|
128
81
|
}
|
|
129
|
-
|
|
130
|
-
return data;
|
|
82
|
+
return response.json();
|
|
131
83
|
}
|
|
132
|
-
// Method to check if Ollama service is available
|
|
133
84
|
async isAvailable() {
|
|
134
85
|
try {
|
|
135
86
|
const response = await fetch(`${this.baseUrl}/api/tags`);
|
|
@@ -139,7 +90,6 @@ export class OllamaService {
|
|
|
139
90
|
return false;
|
|
140
91
|
}
|
|
141
92
|
}
|
|
142
|
-
// Method to list available models
|
|
143
93
|
async listModels() {
|
|
144
94
|
try {
|
|
145
95
|
const response = await fetch(`${this.baseUrl}/api/tags`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ollama-service.js","sourceRoot":"","sources":["../../src/services/ollama-service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"ollama-service.js","sourceRoot":"","sources":["../../src/services/ollama-service.ts"],"names":[],"mappings":"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"}
|