Documentation

Advanced config

advanced.yaml – embeddings, search, clustering, AI timeouts, and prompts for power users.

Everything in Settings has a sensible default. For the knobs that don’t belong in a Settings window, there is advanced.yaml:

~/Library/Containers/com.gisti.app/Data/Library/Application Support/com.gisti.app/advanced.yaml

Settings → Storage → Location opens that folder directly in Finder – easier than typing the path by hand. Gisti writes the file itself on first launch, with every key present and commented; edit the ones you want and restart. Keys added by later versions take their defaults, so an old file keeps working.

Sections

embedding:
  modelId: mlx-community/Qwen3-Embedding-0.6B-4bit-DWQ
  queryInstruction: "Retrieve relevant documents and notes matching the search query"
  maxTokenLength: 1024
  maxBatchSize: 4
  gpuCacheLimitMb: 512
  maxTextLength: 4000
  indexBatchSize: 8
  indexBatchSleepMs: 200
  textChunkPreviewLength: 200

search:
  minSimilarity: 0.4      # semantic match threshold
  topK: 20                # candidates per search
  similarTopK: 5          # candidates for the "Similar" accordion
  similarMinSimilarity: 0.55
  topicsTopK: 50          # candidates feeding Topics clustering
  rrfK: 60                # Reciprocal Rank Fusion constant (hybrid search)
  debounceMs: 250
  itemTextCap: 16384      # per-item text length fed to the index
  savedQueries: []        # queries offered in the ⌘F menu; see Stream → Saved searches

fuzzy:
  minWordLength: 4        # shorter words match exactly only
  maxEditDistance: 1      # typos tolerated per word
  exactMatchSkipThreshold: 20
  maxResults: 5

clustering:
  maxIterations: 30       # KMeans iteration cap
  maxTopics: 60           # runaway guard on the initial k; the real count is sqrt(N/2)
  minVectors: 4           # elements needed to form a topic
  minItemChars: 4         # shorter records skip clustering and go to Unsorted
  labelCandidateCount: 100  # items sampled per cluster when naming it
  labelTextScanLimit: 300 # characters of item text read when its title is generic
  labelMinItems: 2        # items of a topic a word must appear in to name it
  labelMaxTokenLength: 20 # longest token that can be a name (a base64 run isn't a word)
  labelMinScore: 0.07     # naming threshold, 0..1 – see below
  minNamedTopics: 8       # give at least this many a single-word name
  maxClusterShare: 0.06   # topics larger than this share (but never smaller than
                          # two average topics) get split in two

aiTimeouts:
  summarizeSeconds: 60
  chatSeconds: 120
  titleSeconds: 30
  testSeconds: 10

aiLimits:
  summarizeInputMaxChars: 10000
  summarizeMaxTokens: 8192
  chatMaxTokens: 4096
  titleMaxTokens: 32
  attachmentTextMaxChars: 20000
  attachmentImageMaxDimension: 1568
  askAIContextMaxChars: 40000    # text budget for the whole Ask AI request
  askAIContextMaxImages: 8       # images per Ask AI request, counted separately
  attachmentMaxFileBytes: 10485760
  attachmentImageMaxFileBytes: 52428800
  digestInputMaxChars: 20000     # char budget for the Gist-mode digest prompt
  digestItemsPerTypeMax: 50      # per-type item cap when sampling for the digest

clipboard:
  pollIntervalSeconds: 0.2
  maxTextLength: 5000000   # 0 disables the limit; longer copies are skipped, not truncated
  ignorePasteboardTypes:   # copies carrying one of these types are never recorded
    - com.agilebits.onepassword
    - net.antelle.keeweb
    - de.petermaurer.TransientPasteboardType
    - "Pasteboard generator type"
    - com.typeit4me.clipping
  ignoreRegexps: []        # text matching any of these is never recorded
  maxRichTextBytes: 131072 # largest RTF/HTML kept beside a clip; 0 stores plain text only

peek:
  holdDelaySeconds: 0.3     # Force Touch hold before the preview appears
  fadeOutSeconds: 0.15
  pressureOpacityBase: 0.3  # opacity ramp while building up Force Touch pressure
  pressureOpacityGain: 0.58

snap:
  topOffset: 150            # px from the top edge when snapping the window

ui:
  showWhitespaceMarker: true  # flag clips that start or end with a space/newline

contentViews:
  detectMaxBytes: 5000000   # longest record offered a format chip
  tableMaxRows: 1000        # rows of a CSV/TSV table shown at once; copying is never capped

markdown:
  loadRemoteImages: true    # false: remote images in markdown stay placeholders, nothing is fetched

syntaxHighlight:
  maxBytes: 262144          # longest text that gets syntax colors
  maxBlockBytes: 65536      # longest single ``` block that gets them
  detectCodeNotes: true     # open a note that is code with colors and a language chip
  codeNoteMaxBytes: 32768   # longest record that guess is attempted on
  codeNoteMinLines: 5       # shorter than this is a command or a sentence, not a file
  codeNoteMinRelevance: 8   # floor under the winning language's score
  codeNoteRelevanceGap: 4   # how far ahead of the runner-up it must finish
  codeNoteRelevanceGapFromEditor: 2  # …when the clip came from an editor or terminal
  codeNoteRelevanceGapShare: 0.15    # the same lead as a share of the winner's own score
  codeNoteRelevanceGapShareFromEditor: 0.08

prompts:
  summarization: >
    You are a concise summarization assistant. ...
  dailyDigest: >
    Create a digest based on the following notes, clipboard items, ...
  digestSystem: >
    You are a digest assistant that summarizes a user's personal activity ...
  chatSystem: >
    You are a helpful AI assistant. Answer questions, discuss ideas, ...
  titleGeneration: >
    Generate a very short title (3-6 words) for a chat ...
Section What it controls
embedding MLX model id, query instruction, token/batch limits, GPU cache, indexing batches
search semantic thresholds, top-K, similar-items and Topics candidate counts, hybrid ranking (RRF), debounce, per-item text cap, saved searches
fuzzy typo tolerance and result caps for text search
clustering Topics: max topics, KMeans iterations, and how topics get named
aiTimeouts per-request-type timeouts in seconds
aiLimits input/output size caps: summarize/chat/title token limits, attachment text/image/file caps, Ask AI context budget, digest sampling budget
clipboard clipboard poll interval, max copied-text length, ignore rules by pasteboard type and by content, ceiling on kept formatting
peek Force Touch preview: hold delay, fade-out, and pressure-opacity curve
snap window snapping: top-edge offset
ui whether a stream row flags leading/trailing whitespace in the clip or note it shows
contentViews Formatted views: largest record offered a chip, rows of a table shown at once
markdown whether rendered markdown may fetch the remote images it references
syntaxHighlight syntax colors: size ceilings, and how reluctant the app is to call a note code
prompts system prompts: summarization, daily digest, digest system prompt, chat, title generation

Tuning how topics are named

labelMinScore is the one knob worth touching if topic names don’t feel right. It runs on a 0…1 scale, where 1 means “this word is in every item of the topic and in no other topic”. The default 0.07 reads as the word appears in about 7% of the topic’s items and is unique to it.

The threshold never removes a topic – it only decides whether the card gets a single word or a two-word name like Docker · compose.

  • Too many two-word names – lower it (0.04–0.05). More topics get a single-word name, some of them weak.
  • Names look arbitrary – raise it (0.12–0.2). Fewer single words, more two-word labels, which say more anyway.

minNamedTopics is the floor: if fewer topics than that clear the threshold, the best of the rest get a single-word name anyway.

labelMinItems is the other useful knob. A word one item happens to contain isn’t what a topic is about, and letting it compete also drags down the score of every word that is characteristic. Raise it if names still look like they came from whatever you copied last.

Esc

Type to search every page of the manual.