kdeps-resource-search-local
v2.65.0The `search_local` component searches a local directory by content keyword and/or filename glob and returns `{results, count}`. It is a kdeps component from the `components` asset set: call it with a `component:` resource, no install step. Its call is the kdeps API's `search_local` tool, which runs the native searchLocal executor. A workflow that uses `searchLocal:` directly - primary or in a `before:`/`after:` step - is rejected. See [Search resources](https://kdeps.com/workflow/resources/search) for how it relates to `web_search`.
Usage
Built into kdeps: no install. Add it to a resource under the searchLocal: key.
Documentation
search_local component
The search_local component searches a local directory by content keyword and/or filename glob and returns {results, count}. It is a kdeps component from the components asset set: call it with a component: resource, no install step. Its call is the kdeps API's search_local tool, which runs the native searchLocal executor. A workflow that uses searchLocal: directly - primary or in a before:/after: step - is rejected. See Search resources for how it relates to web_search.
It works in both modes: as a DAG step in workflow mode, and inside any workflow the LLM calls as a tool in agent mode.
direction: right
call: "component: search_local" {shape: oval}
api: "POST /tools/search_local/call"
walk: "walk the folder:\nglob + keyword"
index: "index: true:\nTF-IDF + optional graphBoost"
out: "{results, count}" {shape: oval}
call -> api
api -> walk: "index: false (default)"
api -> index: "index: true"
walk -> out
index -> out
Configuration
# resources/search.yaml
actionId: search
name: Search
component:
name: search_local # from the components asset set; a components/search_local/ of your own wins
with:
path: "{{ get('path', '/data') }}" # directory to search; empty searches the working project's folders
query: "{{ get('query') }}" # keyword in file contents; query or glob is required
glob: "{{ get('glob', '') }}" # optional filename pattern, e.g. *.md
limit: 10 # max results, default 3
| Input | Type | Required | Default | Description |
|---|---|---|---|---|
query | string | query or glob | - | Case-insensitive keyword or regex to find in file contents |
path | string | no | working project | Directory to search recursively. An absolute path is recommended |
glob | string | no | - | Filename glob pattern (e.g. *.md, report_*.csv) |
limit | number | no | 3 | Max results |
index | bool | no | false | Build/use a persistent TF-IDF index instead of walking every search |
fuzzy | bool | no | false | Levenshtein fuzzy term matching (requires index: true) |
maxDistance | integer | no | 2 | Max edit distance for fuzzy matching |
indexDBPath | string | no | ~/.kdeps/projects/<folder>-<hash>/index.db | Where the index is stored |
graphBoost | bool | no | false | Re-rank indexed results from the vault graph when the folder is inside it, otherwise from the folder's link/topic graph (requires index: true) |
When both query and glob are set, a file must match both to be included.
Output
{
"results": [{"path": "/data/2024-invoice.md", "name": "2024-invoice.md", "size": 812, "isDir": false}],
"count": 1
}
Read it with output('search').results and output('search').count.
Each result object:
| Key | Type | Description |
|---|---|---|
path | string | Full file path |
name | string | Filename |
size | integer | File size in bytes |
isDir | bool | Always false |
What the walk skips
The walk prunes directories that only ever hold binaries, generated output, or caches: every dot-directory (.git, .codeql-db, .venv, .cache, ...) and the vendor/build/cache names node_modules, bower_components, vendor, target, build, bin, obj, __pycache__, site-packages, coverage, dist-packages, tmp. Their contents would otherwise crowd real documents out of the limit.
Files larger than 1 MiB are skipped too - they are neither glob-matched nor content-matched.
The path you pass is always searched, even when it is a dot-directory such as path: "/workspace/.config-app". Indexed mode (index: true) applies the same directory and size skips when it builds the index.
Examples
Find all Markdown files:
# resources/find-docs.yaml
actionId: findDocs
component:
name: search_local
with:
path: "/workspace/docs"
glob: "*.md"
Find files containing a keyword:
# resources/find-invoices.yaml
actionId: findInvoices
component:
name: search_local
with:
path: "/data/uploads"
query: "overdue"
limit: 20
Feed results into an LLM:
# resources/find-files.yaml
actionId: findFiles
component:
name: search_local
with:
path: "/data/reports"
query: "{{ get('query') }}"
---
actionId: answer
requires: [findFiles]
chat:
model: llama3.2:1b
prompt: "Files found: {{ output('findFiles').results }}. Summarize."
Indexed search (ranked results)
index: true switches the executor from a plain directory walk to a persistent TF-IDF inverted index, giving each result a relevance score instead of just a yes/no filename/content match. The index is built once (or incrementally reused) at ~/.kdeps/projects/<folder>-<hash>/index.db and speeds up repeated searches of the same folder. Nothing is written into the searched folder, so a git repository stays clean.
# resources/search-indexed.yaml
actionId: searchDocs
component:
name: search_local
with:
path: "/workspace/docs"
query: "authentication flow"
index: true # build/use a persistent TF-IDF index instead of walking every search
fuzzy: true # optional: Levenshtein fuzzy matching (requires index: true)
maxDistance: 2 # optional: max edit distance for fuzzy matching, default 2
indexDBPath: "/custom/index.db" # optional: override the default ~/.kdeps/projects/<folder>-<hash>/index.db
graphBoost: true # optional: re-rank from the vault graph, or the folder's link/topic graph outside it (requires index: true)
How graphBoost ranks results
Indexed search already ranks by TF-IDF. graphBoost then moves a document up when one of the top 5 matches connects to it.
When path is the knowledge vault, or a folder inside it, kdeps brings that vault's structural graph current (links, tags, and frontmatter; no model call) and reads those edges. It does not write graph.db. An extracted reference is boosted 25%. A weaker edge is boosted by less: an inferred edge by its confidence, an ambiguous edge by 0.3 times its confidence, and a shared tag by 0.3 of that. A folder outside the vault builds a link/topic graph of the folder (markdown links and shared topics: / tags: frontmatter) at ~/.kdeps/projects/<folder>-<hash>/graph.db, and every connected document gets the full 25%.
A lower-scoring connected document can outrank a higher-scoring isolated one. That matters when the top match is a short index page.
# resources/search-graph.yaml
actionId: findRelatedDocs
component:
name: search_local
with:
path: "/workspace/docs"
query: "{{ get('query') }}"
index: true
graphBoost: true
Indexed-mode output
Indexed-mode output rows add three fields on top of the base result shape:
| Key | Type | Description |
|---|---|---|
score | float | TF-IDF relevance score (post-boost when graphBoost is set) |
matchCount | integer | Number of distinct query terms matched |
snippet | string | Text excerpt around the match |
Errors
| Error | Cause |
|---|---|
search_local: give a query (or a glob) to search for | Neither query nor glob is set |
search_local: ... blocked | path is a filesystem root (/) |
component "search_local" not found | The components asset set is not installed - run kdeps update |
See also
- Search resources - overview and
web_search - Knowledge - the vault graph
graphBoostreads whenpathis inside the vault
Versions
| Version | Published | Status |
|---|---|---|
| 2.65.0 | 10/29/2026 | active |
| 2.64.0 | 10/28/2026 | active |
| 2.63.0 | 10/25/2026 | active |
| 2.62.0 | 10/25/2026 | active |
| 2.61.0 | 10/23/2026 | active |
| 2.60.0 | 10/22/2026 | active |
| 2.59.0 | 10/21/2026 | active |
| 2.58.2 | 10/12/2026 | active |
Details
- Author
- kdeps
- License
- Apache-2.0
- Latest Version
- 2.65.0
- Published
- 10/12/2026