I would like DT to automatically rename the document. It should recognize the date of the document and place the date in the format year-month-day at the beginning. Then, it should automatically learn what the names should be based on the documents that already have names. How can I do this?
That is incorrect. DEVONthink has had its own internal AI for over 20 years. DEVONthink 4 allows access to external AI complementing our internal AI. And these things are covered in the sections of the help and blog posts that have been mentioned.
This is how I have set up auto-renaming with a local LLM on DEVONthink 4. The quality is not great, it gives me an acceptable filename less than half the time, but it sure beats renaming every single file by hand. However, it does not look at existing filenames, only at the document being renamed.
# Install ollama from https://ollama.com/download
# or via homebrew (https://brew.sh)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install ollama
# List ML models in ollama
ollama list
# Install your models of choice
# These are the ones I have tried, not really sure which is better
ollama pull gemma3
ollama pull mistral
# Install ollama service to run in the background if you used homebrew
brew services start ollama
# Configure DT4 to use Ollama
Go to Settings > AI
Provider: Ollama
Ollama URL: http://localhost:11434/api/chat/
Then I used the Rename to Chat suggestion Smart Rule and modified the naming convention (under the Change Name action to my preference (including triggering the rename when a scan lands in my inbox).
I have a DT3 script (AppleScript) mapped to a hotkey (^F). I click on a document to highlight it, press ^F, and I get a list of suggested names based on previous documents in my database. I choose a name and click OK. The document is then renamed. I then use a separate rule (which has the hotkey ^D) to add a sortable date to the beginning of the file’s name. First, there’s the script, which I’ve added to the Script menu as “Rename From See Also.scpt”:
-- Rename record from See Also suggestion's name
use AppleScript version "2.4"
use framework "Foundation"
use scripting additions
property maxLength : 125 -- truncate group names
property truncateEnd : false -- truncate end instead of middle
property deduplicate : false -- deduplicate group names
tell application id "DNtp"
try
set theRecords to selected records
if theRecords = {} or (count theRecords) > 1 then error "Please select one record"
set theRecord to item 1 of theRecords
set theText to plain text of theRecord
if theText = "" then error "No text to compare to"
set theParent_UUID to uuid of location group of theRecord
set theSeeAlsoResults_record to {}
repeat with thisDatabase in databases
set theSeeAlsoResults to compare content theText to thisDatabase
repeat with thisResult in theSeeAlsoResults
set thisParent to location group of thisResult
set thisParent_UUID to uuid of thisParent
if thisParent_UUID ≠theParent_UUID then
set thisName_truncated to my truncateText(name without extension of thisResult)
set end of theSeeAlsoResults_record to {name_:thisName_truncated, score_:(score of thisResult), uuid_:thisParent_UUID}
end if
end repeat
end repeat
if theSeeAlsoResults_record = {} then error "No See Also suggestions found"
set theSeeAlsoResults_record_sorted to my sort(theSeeAlsoResults_record)
set theUUIDs to {}
set chooseFromListItems to {}
repeat with this_record in theSeeAlsoResults_record
set thisUUID to uuid_ of this_record
set thisName_truncated to name_ of this_record
if deduplicate = true then
if thisUUID is not in theUUIDs then
set end of chooseFromListItems to thisName_truncated & linefeed & thisUUID
set end of theUUIDs to thisUUID
end if
else
set end of chooseFromListItems to thisName_truncated & linefeed & thisUUID
end if
end repeat
set theWidthPlaceholder_list to {}
repeat maxLength times
set end of theWidthPlaceholder_list to space
end repeat
set theWidthPlaceholder to my tid(theWidthPlaceholder_list, "")
tell application "SystemUIServer"
activate
set theChoice to choose from list chooseFromListItems & {theWidthPlaceholder} with prompt "Rename record to:" default items (item 1 of chooseFromListItems) with title ""
end tell
activate
if theChoice is false or item 1 of theChoice = theWidthPlaceholder then return
set theChoiceName to item 1 of paragraphs of (item 1 of theChoice)
set nondatedChoiceName to do shell script "echo " & quoted form of theChoiceName & " | sed 's/^....-..-.. //'"
set name of theRecord to nondatedChoiceName
on error error_message number error_number
if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
return
end try
end tell
on sort(theList)
set anArray to current application's NSArray's arrayWithArray:theList
set theDesc to current application's NSSortDescriptor's sortDescriptorWithKey:"score_" ascending:false selector:"compare:"
set newList to (anArray's sortedArrayUsingDescriptors:{theDesc}) as list
end sort
on truncateText(theText)
try
if (length of theText) > maxLength then
if truncateEnd = true then
set theText_trucated to ((characters 1 thru (maxLength - 1) in theText) & "…") as string
else
set x to round ((maxLength / 2) - 1)
set theStart to characters 1 thru x in theText as string
set theEnd to characters -x thru -1 in theText as string
set theText_trucated to (theStart & "…" & theEnd) as string
end if
return theText_trucated
else
return theText
end if
on error error_message number error_number
activate
display alert "Error: Handler \"truncateText\"" message error_message as warning
error number -128
end try
end truncateText
on tid(theList, theDelimiter)
set d to AppleScript's text item delimiters
set AppleScript's text item delimiters to theDelimiter
set theString to theList as text
set AppleScript's text item delimiters to d
return theString
end tid