tune-basic-toolset 0.1.20 → 0.1.22

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/README.md CHANGED
@@ -17,6 +17,7 @@ Basic toolset for [Tune](https://github.com/iovdin/tune).
17
17
  - [search_tools](#search_tools) find appropriate tools for a task
18
18
  - [osa](#osa) manage reminders/notes/calendar (AppleScript/macOS)
19
19
  - [jina_r](#jina_r) fetch webpage content
20
+ - [mistral_ocr](#mistral_ocr) extract text from documents and images via OCR
20
21
  - [websearch](#websearch) search the web with web-enabled llms
21
22
  - [list](#list) keep list of tasks todo (loops for LLM)
22
23
  - [sqlite](#sqlite) execute sqlite queries
@@ -207,15 +208,42 @@ TODOS:
207
208
  Find appropriate tools for a given task by searching through available tools
208
209
  ```chat
209
210
  user: @search_tools
210
- I need to work with a database and manage todos
211
+ what is in my current directory?
212
+
213
+ assistant:
214
+ I'll help you check what's in your current directory.
211
215
 
212
- A:
216
+ tool_call: search_tools
217
+ list files and folders in current directory
213
218
 
214
- tool_call: search_tools
215
- I need to work with a database and manage todos
216
219
  tool_result:
217
- @sqlite "sqlite" - because it helps to execute sqlite queries on databases
218
- @list "list" - because it helps with managing todo lists and tasks
220
+ @sh "sh" - because it can run shell commands like `ls -la` to list files/folders on Unix-like systems
221
+ @cmd "cmd" - because it can execute `dir` to list directory contents on Windows cmd.exe
222
+ @powershell "powershell" - because it can run `Get-ChildItem` (alias `ls`) to list items on Windows PowerShell
223
+ @nu "nu" - because it can run Nushell commands like `ls` for structured directory listings
224
+
225
+ assistant:
226
+ Let me try with a shell command that works on most systems:
227
+
228
+ tool_call: sh
229
+ ls -la
230
+
231
+ tool_result:
232
+ total 13584
233
+ drwxr-xr-x 15 iovdin staff 480 Jan 18 19:07 .
234
+ drwxr-xr-x 195 iovdin staff 6240 Jan 17 12:46 ..
235
+ drwxr-xr-x 14 iovdin staff 448 Jan 18 19:00 .git
236
+ drwxr-xr-x 3 iovdin staff 96 Sep 4 20:15 .github
237
+ -rw-r--r-- 1 iovdin staff 82 Aug 12 10:44 .gitignore
238
+ -rw-r--r-- 1 iovdin staff 316 Oct 21 21:41 .npmignore
239
+ drwxr-xr-x 32 iovdin staff 1024 Jan 18 18:59 chats
240
+ drwxr-xr-x 13 iovdin staff 416 Oct 25 09:32 node_modules
241
+ -rw-r--r-- 1 iovdin staff 8145 Oct 25 09:32 package-lock.json
242
+ -rw-r--r-- 1 iovdin staff 754 Jan 18 18:59 package.json
243
+ -rw-r--r-- 1 iovdin staff 18959 Jan 18 18:59 README.md
244
+ drwxr-xr-x 62 iovdin staff 1984 Jan 18 19:04 src
245
+ drwxr-xr-x 16 iovdin staff 512 Nov 9 09:14 test
246
+
219
247
  ```
220
248
 
221
249
  This tool analyzes your task description and recommends the most relevant tools from the available toolset, explaining why each tool would be helpful for your specific use case.
@@ -264,6 +292,40 @@ Tune is a versatile toolkit designed for developers and users to effectively int
264
292
  <cut for brevity>
265
293
  ```
266
294
 
295
+ ### `mistral_ocr`
296
+ Extract text from documents and images using the [Mistral OCR API](https://mistral.ai/). Requires a `MISTRAL_KEY` set in `.env`.
297
+
298
+ Supports documents: `.pdf`, `.docx`, `.pptx`, `.txt`, `.epub`, `.xml`, `.rtf`, `.odt`, `.bib`, `.fb2`, `.ipynb`, `.tex`, `.opml`, `.1`, `.man`
299
+
300
+ Supports images: `.jpg`, `.jpeg`, `.png`, `.avif`, `.tiff`, `.gif`, `.heic`, `.heif`, `.bmp`, `.webp`
301
+
302
+ ```chat
303
+ user: @mistral_ocr
304
+ extract text from invoice.pdf
305
+
306
+ tool_call: mistral_ocr {"filename":"invoice.pdf"}
307
+ tool_result:
308
+ # Invoice #1042
309
+
310
+ **Date:** 2024-04-01
311
+ **Bill To:** Acme Corp
312
+
313
+ | Description | Amount |
314
+ |--------------------|---------|
315
+ | Consulting (10h) | $1500 |
316
+ | Hosting (1 month) | $50 |
317
+ | **Total** | $1550 |
318
+
319
+ user:
320
+ what does this screenshot say?
321
+
322
+ tool_call: mistral_ocr {"filename":"screenshot.png"}
323
+ tool_result:
324
+ ## System Alert
325
+
326
+ Your disk usage has exceeded 90%. Please free up space to avoid performance issues.
327
+ ```
328
+
267
329
  ### `websearch`
268
330
  Search the web with web enabled llms
269
331
  Supports search with `perplexity/sonar`, `perplexity/sonar-pro`, `gpt-4o-search-preview`, `gpt-4o-mini-search-preview` models via the `model` parameter (defaults to `perplexity/sonar`).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tune-basic-toolset",
3
- "version": "0.1.20",
3
+ "version": "0.1.22",
4
4
  "description": "Basic toolset for tune",
5
5
  "main": "src/index.js",
6
6
  "files": [
package/src/init.proc.js CHANGED
@@ -6,10 +6,7 @@ module.exports = async function init(node, args, ctx) {
6
6
 
7
7
  // include file
8
8
  if (content.indexOf("@") === 0) {
9
- return {
10
- type: "text",
11
- read: async () => this.read(content.replace(/^@{1,2}/, ""))
12
- }
9
+ return ctx.resolve(content.replace(/^@{1,2}/, ""))
13
10
  }
14
11
 
15
12
  return {
@@ -18,5 +18,5 @@
18
18
  },
19
19
  "required": ["url"]
20
20
  },
21
- "$escape_output": false
21
+ "$escape_output": true
22
22
  }
@@ -0,0 +1,14 @@
1
+ {
2
+ "description": "Perform OCR on a local files using Mistral OCR API, returns extracted text as markdown",
3
+ "parameters": {
4
+ "type": "object",
5
+ "properties": {
6
+ "filename": {
7
+ "type": "string",
8
+ "description": "Path to the file to perform OCR on"
9
+ }
10
+ },
11
+ "required": ["filename"]
12
+ },
13
+ "$escape_output": true
14
+ }
@@ -0,0 +1,74 @@
1
+ const path = require('path');
2
+
3
+ const MIME_TYPES = {
4
+ // Documents → document_url
5
+ '.pdf': { kind: 'document', mime: 'application/pdf' },
6
+ '.docx': { kind: 'document', mime: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' },
7
+ '.pptx': { kind: 'document', mime: 'application/vnd.openxmlformats-officedocument.presentationml.presentation' },
8
+ '.txt': { kind: 'document', mime: 'text/plain' },
9
+ '.epub': { kind: 'document', mime: 'application/epub+zip' },
10
+ '.xml': { kind: 'document', mime: 'application/xml' },
11
+ '.rtf': { kind: 'document', mime: 'application/rtf' },
12
+ '.odt': { kind: 'document', mime: 'application/vnd.oasis.opendocument.text' },
13
+ '.bib': { kind: 'document', mime: 'application/x-bibtex' },
14
+ '.fb2': { kind: 'document', mime: 'application/x-fictionbook+xml' },
15
+ '.ipynb': { kind: 'document', mime: 'application/x-ipynb+json' },
16
+ '.tex': { kind: 'document', mime: 'application/x-tex' },
17
+ '.opml': { kind: 'document', mime: 'text/x-opml' },
18
+ '.1': { kind: 'document', mime: 'application/x-troff-man' },
19
+ '.man': { kind: 'document', mime: 'application/x-troff-man' },
20
+ // Images → image_url
21
+ '.jpg': { kind: 'image', mime: 'image/jpeg' },
22
+ '.jpeg': { kind: 'image', mime: 'image/jpeg' },
23
+ '.png': { kind: 'image', mime: 'image/png' },
24
+ '.avif': { kind: 'image', mime: 'image/avif' },
25
+ '.tiff': { kind: 'image', mime: 'image/tiff' },
26
+ '.gif': { kind: 'image', mime: 'image/gif' },
27
+ '.heic': { kind: 'image', mime: 'image/heic' },
28
+ '.heif': { kind: 'image', mime: 'image/heif' },
29
+ '.bmp': { kind: 'image', mime: 'image/bmp' },
30
+ '.webp': { kind: 'image', mime: 'image/webp' },
31
+ };
32
+
33
+ module.exports = async function mistralOcr({ filename }, ctx) {
34
+ const apiKey = await ctx.read("MISTRAL_KEY");
35
+ if (!apiKey) {
36
+ throw new Error("MISTRAL_KEY is not set");
37
+ }
38
+
39
+ const ext = path.extname(filename).toLowerCase();
40
+ const typeInfo = MIME_TYPES[ext];
41
+ if (!typeInfo) {
42
+ throw new Error(`Unsupported file extension: ${ext}`);
43
+ }
44
+
45
+ const buf = await ctx.read(filename);
46
+ const base64 = buf.toString('base64');
47
+ const dataUrl = `data:${typeInfo.mime};base64,${base64}`;
48
+
49
+ const document = typeInfo.kind === 'image'
50
+ ? { type: 'image_url', image_url: dataUrl }
51
+ : { type: 'document_url', document_url: dataUrl };
52
+
53
+ const response = await fetch("https://api.mistral.ai/v1/ocr", {
54
+ method: "POST",
55
+ headers: {
56
+ "Content-Type": "application/json",
57
+ "Authorization": `Bearer ${apiKey}`,
58
+ },
59
+ body: JSON.stringify({
60
+ model: "mistral-ocr-latest",
61
+ document,
62
+ include_image_base64: true,
63
+ }),
64
+ });
65
+
66
+ if (!response.ok) {
67
+ const errorText = await response.text();
68
+ throw new Error(`Mistral OCR error: ${response.status} ${response.statusText} - ${errorText}`);
69
+ }
70
+
71
+ const result = await response.json();
72
+
73
+ return result.pages.map(page => page.markdown).join("\n\n");
74
+ };
@@ -1,5 +1,6 @@
1
1
  system:
2
- @{ gpt-5 | prop reasoning_effort=low }
2
+ @{ small | init @gpt-5.2-chat-latest }
3
+
3
4
  Given user task
4
5
  You provide a list of tools that are best help for the user
5
6
 
@@ -5,11 +5,11 @@
5
5
  "properties": {
6
6
  "text": {
7
7
  "type": "string",
8
- "description": "The shell command to execute"
8
+ "description": "The shell command to execute, always prepend input with comment explaining the command so user that is not familiar with shell can understand and estimate how dangerous the command is"
9
9
  },
10
10
  "host": {
11
11
  "type": "string",
12
- "description": "remote host like user@host.com to execute the shell comand on (uses ssh)"
12
+ "description": "remote host like user@host.com to execute the shell comand on (uses ssh), default is empty (local shell) "
13
13
  }
14
14
  },
15
15
  "required": ["text"]