Hi all,
I’m learning a bit about the new ‘perform chat research’ command in 4.2.2. This is quite something. I had Gemini build an AppleScript that uses this new command, and the results so far seem quite impressive.
What I find interesting is that it is not actually reading the contents of, in my particular case, my journal articles database. Instead, as near as I can figure (based on how Gemini is explaining it to me) it is looking for specific strings of text and has DEVONthink generate an ‘abstract’ that is then synthesised in some output that leverages whichever AI tool you’ve selected in Preferences.
Still learning about what this does, and I’m still playing around with the full Apple Script itself, but just wanted to flag it here for others’ benefit.
You asked Gemini to write an AppleScript where…?
The command is basically what the chat assistant (and likewise the Chat - Query smart action and the get chat response for message AppleScript command) uses when researching one or more sources, therefore the Web & Wikipedia options in Settings > AI > Search matter too. And the default AI provider (see Settings > AI > Chat) is used to filter the results.
However, so far the snippets/abstracts are generated by DEVONthink, not by external AI, as the main use case for these results is to use them in additional AI requests (just like the chat assistant doesn’t present the raw results but instead uses the search results to build the response)
In case that anyone’s interested I could provide an example script…
Thanks Christian - yes, would love to see an example script.
Jim: right now, the script just lives in the DT script menu.
The promised example:
-- Research Report
tell application id "DNtp"
show progress indicator "Research Report"
try
set theReviewMessage to "Enter the research topic:"
try
set theReviewResult to display dialog theReviewMessage buttons {"Reject", "Approve"} default button "Approve" with title "Research Report" default answer ""
set theUserResponse to text returned of theReviewResult
set theButtonPressed to button returned of theReviewResult
if theButtonPressed is "Approve" then
set theSources to {"web"}
set theResearchQuery to theUserResponse
set ctx_research to ""
try
set ctx_research to perform chat research theResearchQuery sources theSources maximum results 10
end try
set theNormalized to {}
repeat with r in ctx_research
set theText to text content of r
if theText is "" then set theText to abstract of r
set end of theNormalized to {|title|:title of r, |link|:URL of r, |authors|:authors of r, |text|:theText, |abstract|:abstract of r}
end repeat
set ctx_research to theNormalized
end if
end try
set theEntriesList to {}
repeat with r in ctx_research
set ctx_title to |title| of r
set ctx_link to |link| of r
set ctx_authors to |authors| of r
set ctx_text to |text| of r
set ctx_abstract to |abstract| of r
set end of theEntriesList to "### " & ctx_title & "" & return & "" & ctx_text & "" & return & "[Source](" & ctx_link & ")"
end repeat
if (count of theEntriesList) is 0 then error
set ctx_report to "# Research Report" & return & "" & return & "" & my joinList(theEntriesList, linefeed & linefeed) & "" & return & ""
set ctx_polished to ""
set theGenPrompt to "<report>" & ctx_report & "</report>"
set theGenRole to "You are a research editor. Rewrite the following collected research into a polished, well-structured Markdown report. Preserve all source links and key facts. Organise under clear section headings."
try
set theGenResult to get chat response for message theGenPrompt role theGenRole
if theGenResult is not missing value then set ctx_polished to theGenResult
end try
set theDocName to theUserResponse
set theDocContent to ctx_polished
set theTargetDB to current database
set theTargetGroup to create location "/Research" in theTargetDB
set theRecord to create record with {name:theDocName, type:markdown, content:theDocContent} in theTargetGroup
end try
hide progress indicator
end tell
on joinList(theList, theDelimiter)
set oldDelims to AppleScript's text item delimiters
set AppleScript's text item delimiters to theDelimiter
set theResult to theList as string
set AppleScript's text item delimiters to oldDelims
return theResult
end joinList
P.S: Automatically generated and only slightly polished but fully functional.
P.P.S: But it’s not AI generated, @chrillek 
6 Likes
Apologies for resurrecting this, but quick question: is there a hard limit of the number of items queried when using ‘perform chat research’? When deploying a script, I seem to top out at 32.
Here is the script:
tell application id "DNtp"
try
-- Step 1: Query dialog
display dialog "Enter your research query:" default answer "" with title "Quick Query"
set searchKeywords to text returned of result
-- Step 2: Target destination
set targetDestination to incoming group
-- Step 3: Search DEVONthink
show progress indicator "Quick Query" steps 4
step progress indicator "Searching DEVONthink..."
set researchResults to perform chat research searchKeywords sources {"databases"} maximum results 120
-- Handle empty results
if researchResults is missing value or (count of researchResults) = 0 then
hide progress indicator
display alert "No relevant fragments found." message "Try a different query." as warning
return
end if
-- Step 4: Build fragment text and reference map
step progress indicator "Processing fragments..."
set collectiveSnippets to ""
set refMap to ""
set refTableRows to ""
set refCounter to 0
repeat with aResult in researchResults
set theUUID to URL of aResult
set theRecord to get record with uuid theUUID
set theTitle to name of theRecord
set refCounter to refCounter + 1
set currentRefID to "REF-" & refCounter
-- Get text content
set usedText to ""
try
set usedText to plain text of theRecord
end try
-- Build collective snippets fragment
if usedText is not "" then
set collectiveSnippets to collectiveSnippets & "<fragment id='" & currentRefID & "'>" & return & "DOCUMENT: " & theTitle & return & "CONTENT: " & usedText & return & "</fragment>" & return
end if
-- Build reference map (REF-N | x-devonthink-item://UUID | Title)
set refMap to refMap & currentRefID & " | " & theUUID & " | " & theTitle & return
-- Build reference table row
set refTableRows to refTableRows & "<tr><td style='padding: 8px;'><a href='" & theUUID & "'>" & currentRefID & "</a></td><td style='padding: 8px;'>" & theTitle & "</td></tr>" & return
end repeat
-- Step 5: Build prompts and call AI
step progress indicator "Querying AI..."
set systemRole to "You are a concise research assistant. Using ONLY the provided document fragments, organize your entire response by document. For EACH document that contains content relevant to the research question, output a section (skip any document with no relevant content — do not mention skipped documents). For each relevant document, output in this exact order: (1) an <h2> subheading formatted exactly as: <h2><a href=" & quote & "x-devonthink-item://UUID" & quote & ">REF-N</a>: Document Title</h2> — look up the UUID and title from the REFERENCE MAP; (2) two to three <p> paragraphs that summarise what this specific document says in relation to the research query — the summary must directly address the query topic first (e.g. if the query is 'Bermuda 1', begin by explaining what the document says about Bermuda 1 specifically) and then convey the document's broader relevant argument or findings — be detailed and specific to the document's actual content — do not use verbatim passages or quotations; (3) a <ul> list with as many <li> items as needed that summarises the key points of this document (not limited to the query — cover the document's main findings and arguments). Do not invent information. Do not merge or synthesize content across documents. Use only <h2>, <p>, <ul>, and <li> HTML tags (no <html>, <head>, <body>, or <blockquote> tags)."
set userMessage to "QUERY: " & searchKeywords & return & return & "REFERENCE MAP:" & return & refMap & return & "<data>" & return & collectiveSnippets & "</data>"
set masterAnswer to get chat response for message userMessage role systemRole temperature 0.3 thinking false tool calls false
-- Step 6: Get current date
set theDate to current date
set theDay to day of theDate as text
set theMonth to (month of theDate as integer) as text
set theYear to year of theDate as text
set dateString to theDay & "/" & theMonth & "/" & theYear
-- Step 7: Assemble final HTML
step progress indicator "Building document..."
set finalHTML to "<html><head><style>h2 { font-size: 14pt; margin-top: 24px; padding-bottom: 4px; border-bottom: 1px dotted #aaa; }</style></head><body style='font-family: Helvetica; font-size: 16pt; line-height: 1.5; max-width: 800px; margin: 20px;'>" & return
set finalHTML to finalHTML & "<h1 style='font-size: 18pt; text-transform: uppercase; border-bottom: 1px solid #ccc;'>" & searchKeywords & "</h1>" & return
set finalHTML to finalHTML & "<p style='font-size: 10pt; color: #666;'>Quick Query - " & dateString & " - " & refCounter & " sources</p>" & return
set finalHTML to finalHTML & masterAnswer & return
set finalHTML to finalHTML & "<hr>" & return
set finalHTML to finalHTML & "<h2 style='font-size: 13pt;'>References</h2>" & return
set finalHTML to finalHTML & "<table border='1' style='width: 100%; border-collapse: collapse;'>" & return
set finalHTML to finalHTML & "<tr><th style='padding: 8px; width: 15%;'>ID</th><th style='padding: 8px;'>Document</th></tr>" & return
set finalHTML to finalHTML & refTableRows
set finalHTML to finalHTML & "</table>" & return
set finalHTML to finalHTML & "</body></html>"
-- Step 8: Create DEVONthink note
set theNote to create record with {name: searchKeywords & " (Quick Query)", type: HTML, content: finalHTML} in targetDestination
hide progress indicator
open tab for record theNote
on error error_message number error_number
hide progress indicator
if error_number is not -128 then
display alert "Error" message error_message buttons {"OK"} default button 1
end if
end try
end tell
There are indeed limits which vary depending on the usage mode and the used AI model and search engine (which have their own limits).
Thanks Christian. I’m hitting an internal (database) source limit of 32 regardless of the model selected.
Is the hard limit thus inside the ‘perform chat research’ command? Is it possible to have an option to increase this?
It is. Depending on the usage mode it’s lower or higher as the AI requests cause additional costs. The main purpose of this command is to feed the results into additional AI requests (just like in the chat assistant or in my example above).
1 Like