Knowledge Bases
The hutly kbs command group manages knowledge bases (KBs) — the searchable document stores Hutly agents query for grounded answers. It covers KB identity (title, description, type), the files inside a KB (upload, list, download, delete, reindex), semantic search, triggers (rules that run an agent or workflow against newly-ingested files), and a YAML round-trip for version control.
All commands operate against the org and credentials resolved from your environment (HUTLY_ORG_ID, HUTLY_API_KEY) or .hutlyrc.yaml — see Configuration. Most read commands emit JSON by default; pass --pretty to indent it. The --json flag is accepted everywhere as a no-op for compatibility.
Identity
list
List the knowledge bases for the current org.
hutly kbs list
hutly kbs list --query lease --limit 25
hutly kbs list --include-personal --pretty| Option | Description |
|---|---|
-q, --query <q> |
Filter KBs by title/description |
-l, --limit <n> |
Max results (default 100) |
-c, --cursor <n> |
Pagination cursor |
--include-personal |
Also include personal KBs created by the caller |
--pretty |
Pretty-print JSON output |
get
Fetch a KB together with the first page of its files and its triggers — the full detail view.
hutly kbs get <kbId>
hutly kbs get <kbId> --prettydescribe
Show only a KB’s metadata. Unlike get, it omits the customInstructions body and does not include files or triggers — use it for a quick identity check.
hutly kbs describe <kbId> --prettycreate
Create a new knowledge base. Both --title and --description are required; the description is LLM-facing — it tells agents when to search this KB.
hutly kbs create \
--title "Tenancy Legislation" \
--description "Search for Australian residential tenancy acts and regulations." \
--type ORGANIZATION| Option | Description |
|---|---|
--title <title> |
KB title (required) |
--description <description> |
LLM-facing description (required) |
--type <type> |
ORGANIZATION or PERSONAL (default ORGANIZATION) |
update
Update a KB’s title and/or description. The API only accepts those two fields. Pass at least one flag — whichever you omit is preserved from the current value.
hutly kbs update <kbId> --title "Tenancy Legislation (VIC)"
hutly kbs update <kbId> --description "Victorian residential tenancy law only."delete
Permanently delete a KB and all its files, pages, and embeddings. Irreversible — prompts for confirmation unless -y is passed.
hutly kbs delete <kbId>
hutly kbs delete <kbId> --yesSearch
search
Semantic (embedding-based) search across knowledge bases. With no --kbId, it searches every accessible KB — your own org’s plus any public KBs anywhere. Pass --kbId (repeatable) to scope to specific KBs.
# Search everything accessible
hutly kbs search "notice period for rent increase"
# Scope to two KBs, raise the result count
hutly kbs search "bond claims" --kbId kb_abc --kbId kb_def --limit 10
# Assert the owning org of a public/legislation KB
hutly kbs search "smoke alarms" --kbId kb_pub --orgId org_legis| Option | Description |
|---|---|
--kbId <id> |
Scope to this KB id; repeat to search a list |
--orgId <id> |
Assert the owning org for each --kbId (repeatable, parallel to --kbId) |
-l, --limit <n> |
Max results (default 5) |
--offset <n> |
Skip the first N results (advanced; raise --limit for more rows) |
--file-pattern <pattern> |
Only search inside files matching this pattern |
--pretty |
Pretty-print JSON output |
When --orgId is supplied, the number of --orgId values must match the number of --kbId values, or the command errors. Semantic search has no page count — to get more matches, raise --limit rather than paging with --offset.
Files
The hutly kbs files group manages the documents inside a KB.
files upload
Upload a local file to a KB. The bytes go directly to S3 via a presigned URL — never through Lambda. By default the command is fire-and-forget (S3 triggers async ingestion); pass --wait to poll until ingestion reaches READY or ERROR.
# Fire-and-forget
hutly kbs files upload <kbId> ./docs/lease.pdf
# Block until ingestion finishes
hutly kbs files upload <kbId> ./docs/lease.pdf --wait --timeout 600
# Override the inferred content type
hutly kbs files upload <kbId> ./data.bin --content-type application/pdf| Option | Description |
|---|---|
--wait |
Poll until ingestion finishes (READY or ERROR) |
--timeout <seconds> |
Wait timeout in seconds (default 300) |
--content-type <type> |
Override the inferred content type |
With --wait, the command exits non-zero on ingestion ERROR or on timeout.
files list
List files in a KB, optionally filtered by name or ingestion status.
hutly kbs files list <kbId>
hutly kbs files list <kbId> --status PROCESSING
hutly kbs files list <kbId> --query lease --limit 50| Option | Description |
|---|---|
-q, --query <q> |
Filter by file name |
-s, --status <status> |
Filter by status: WAITING-UPLOAD, ENQUEUED, PROCESSING, READY, ERROR |
-l, --limit <n> |
Max results (default 100) |
-c, --cursor <n> |
Pagination cursor |
--pretty |
Pretty-print JSON output |
files download
Get a short-lived download link for a KB file. Prints the URL by default, or saves the file body to disk with -o.
# Print a presigned URL
hutly kbs files download <kbId> <fileId>
# Save to disk
hutly kbs files download <kbId> <fileId> -o ./lease.pdf| Option | Description |
|---|---|
-o, --output <file> |
Save the file body to this local path instead of printing the URL |
files delete
Delete a file from a KB, removing its pages and embeddings. Prompts for confirmation unless -y is passed.
hutly kbs files delete <kbId> <fileId>
hutly kbs files delete <kbId> <fileId> --yesfiles reindex
Re-trigger ingestion for a file — re-chunk and re-embed it. Runs asynchronously via SQS. Pass --triggers-only to re-run the KB’s triggers against the file’s existing embeddings without re-chunking or re-embedding.
hutly kbs files reindex <kbId> <fileId>
hutly kbs files reindex <kbId> <fileId> --triggers-only| Option | Description |
|---|---|
--triggers-only |
Only re-run KB triggers against existing embeddings (skip re-chunk + re-embed) |
Triggers
The hutly kbs triggers group manages triggers — rules that run an agent or workflow against newly-ingested KB files. Write operations (create, update, delete) are admin-only. The legacy action-chain trigger type is deprecated and cannot be created or updated from the CLI; existing ones still surface in list/get for visibility.
triggers list
List the triggers configured on a KB.
hutly kbs triggers list <kbId> --pretty| Option | Description |
|---|---|
-l, --limit <n> |
Max results (default 100) |
-c, --cursor <n> |
Pagination cursor |
--pretty |
Pretty-print JSON output |
triggers get
Fetch a single trigger.
hutly kbs triggers get <kbId> <triggerId> --prettytriggers create
Create a trigger (admin-only). --type is required. For agent triggers, --agent-id and --prompt are required; for workflow triggers, --workflow-id is required. Conditions are a JSON array of { field, comparison, value } objects, passed inline or from a file.
# Agent trigger that fires on PDF files
hutly kbs triggers create <kbId> \
--type agent \
--agent-id agt_123 \
--prompt "Summarise this lease and extract key dates." \
--conditions '[{"field":"fileName","comparison":"ENDS_WITH","value":".pdf"}]'
# Workflow trigger, conditions from a file
hutly kbs triggers create <kbId> \
--type workflow \
--workflow-id wf_456 \
--conditions-file ./conditions.json| Option | Description |
|---|---|
--type <type> |
agent or workflow (required) |
--agent-id <id> |
Agent to run (required for type=agent) |
--workflow-id <id> |
Workflow to run (required for type=workflow) |
--prompt <text> |
Prompt passed to the agent (required for type=agent) |
--conditions <json> |
Inline JSON array of condition objects |
--conditions-file <path> |
Read the conditions JSON array from a file |
Pass either --conditions or --conditions-file, not both.
triggers update
Update a trigger (admin-only). The API replaces the trigger fully — pass every field you want kept, with the same required-field rules as create.
hutly kbs triggers update <kbId> <triggerId> \
--type agent \
--agent-id agt_123 \
--prompt "Updated prompt." \
--conditions '[{"field":"fileName","comparison":"CONTAINS","value":"lease"}]'triggers delete
Delete a trigger (admin-only). Prompts for confirmation unless -y is passed.
hutly kbs triggers delete <kbId> <triggerId> --yesYAML round-trip
KBs support a pull/push round-trip so a KB’s identity and triggers can be tracked in version control. push applies only the KB identity (title, description, and type on create) — triggers in the YAML are advisory and are not applied; manage them with hutly kbs triggers. Files are never part of the round-trip — manage them with hutly kbs files.
pull
Fetch a KB and write its identity + triggers to a YAML file. Files are not included.
hutly kbs pull <kbId>
hutly kbs pull <kbId> -o ./kbs/tenancy.yaml| Option | Description |
|---|---|
-o, --output <file> |
Output path (defaults to ./kb-<kbId>.yaml) |
The generated YAML looks like:
knowledgeBaseId: !org_map
your-org-id: kb_abc123
title: Tenancy Legislation
llmDescription: Search for Australian residential tenancy acts and regulations.
type: ORGANIZATION
isPublic: false
triggers:
- type: agent
agentId: agt_123
agentName: Lease Summariser
prompt: Summarise this lease and extract key dates.
conditions:
- field: fileName
comparison: ENDS_WITH
value: .pdfThe knowledgeBaseId is emitted as an !org_map so the same file can resolve to different KB ids per org. The triggers block is informational on push.
push
Create or update a KB from a YAML file. Idempotent on knowledgeBaseId: if the YAML carries one (and --force-new is not set), the KB is updated in place; otherwise a new KB is created and its id is written back into the YAML file. When the YAML contains triggers, push warns that it does not apply them.
# Create or update from YAML
hutly kbs push ./kbs/tenancy.yaml
# Always create a new KB, ignoring any knowledgeBaseId in the file
hutly kbs push ./kbs/tenancy.yaml --force-new
# Substitute a variable used in the YAML
hutly kbs push ./kbs/tenancy.yaml --var env=prod| Option | Description |
|---|---|
--force-new |
Always create a new KB (ignore existing knowledgeBaseId in YAML) |
-v, --var <key=value> |
Set a variable value (repeatable) |
After a create, commit the updated YAML so the written-back knowledgeBaseId is preserved for future idempotent pushes.
All commands exit 0 on success and non-zero on failure, printing the error to stderr.