9aab79d49b
- Remove v1 Python CLI (src/kb_search/, tests/, root pyproject.toml, uv.lock, .venv) - Add Go client with cross-platform build (client/) - Add FastAPI engine with NVIDIA and multi-stage ROCm Dockerfiles (engine/) - Add VERSION files for client and engine, wired into builds - Add release.sh for automated build, tag, release, and Docker push - Update README with build/release docs and ROCm migration note - Clean up .gitignore for v2 project structure Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
184 lines
7.6 KiB
Markdown
184 lines
7.6 KiB
Markdown
# Go Client
|
|
|
|
## Purpose
|
|
|
|
The Go client (`kb`) provides a command-line interface for interacting with the knowledge base engine, supporting search, document ingestion, job tracking, document management, tag management, and status display.
|
|
|
|
## Requirements
|
|
|
|
### Requirement: Single static binary with zero runtime dependencies
|
|
|
|
The Go client SHALL compile to a single static binary with no runtime dependencies. It SHALL support cross-compilation for Linux (amd64, arm64), macOS (amd64, arm64), and Windows (amd64).
|
|
|
|
#### Scenario: Install on a clean machine
|
|
- **WHEN** a user downloads the `kb` binary for their platform
|
|
- **THEN** they SHALL be able to run it immediately with no additional installs (no Python, no Docker, no shared libraries)
|
|
|
|
---
|
|
|
|
### Requirement: Client configuration
|
|
|
|
The client SHALL read configuration from `~/.kb/client.yaml`. Configuration values SHALL be overridable via environment variables and CLI flags. Precedence: CLI flags > environment variables > config file > defaults.
|
|
|
|
#### Scenario: Default configuration
|
|
- **WHEN** no config file exists and no env vars or flags are set
|
|
- **THEN** the client SHALL use defaults: engine URL `http://localhost:8000`, no API key, format `human`
|
|
|
|
#### Scenario: Config file
|
|
- **WHEN** `~/.kb/client.yaml` contains `engine_url: https://kb.example.com`
|
|
- **THEN** the client SHALL use that URL for all API requests
|
|
|
|
#### Scenario: Environment variable override
|
|
- **WHEN** `KB_ENGINE_URL` is set
|
|
- **THEN** it SHALL override the config file value
|
|
|
|
#### Scenario: CLI flag override
|
|
- **WHEN** the user passes `--engine https://other.host:8000`
|
|
- **THEN** it SHALL override both the config file and environment variable
|
|
|
|
#### Scenario: Engine unreachable
|
|
- **WHEN** the client cannot connect to the engine URL
|
|
- **THEN** it SHALL print a clear error message (e.g., "Cannot reach engine at http://localhost:8000 — is it running?") and exit with a non-zero code
|
|
|
|
---
|
|
|
|
### Requirement: Search command
|
|
|
|
The client SHALL provide a `kb search <query>` command that sends the query to the engine and displays results.
|
|
|
|
#### Scenario: Human-readable search output
|
|
- **WHEN** the user runs `kb search "how to change oil"`
|
|
- **THEN** the client SHALL POST to `/api/v1/search`, and display results in a human-readable format showing rank, score, document title, page/section, doc type, tags, and a text snippet
|
|
|
|
#### Scenario: JSON search output
|
|
- **WHEN** the user runs `kb search "query" --format json`
|
|
- **THEN** the client SHALL output the raw JSON response from the engine
|
|
|
|
#### Scenario: Search with filters
|
|
- **WHEN** the user runs `kb search "brakes" --tags maintenance --type pdf --top 3`
|
|
- **THEN** the client SHALL include the filters in the API request body
|
|
|
|
#### Scenario: Search mode flags
|
|
- **WHEN** the user runs `kb search "error" --fts-only`
|
|
- **THEN** the client SHALL set `fts_only: true` in the request body
|
|
|
|
---
|
|
|
|
### Requirement: Add command (file and note ingestion)
|
|
|
|
The client SHALL provide a `kb add` command that uploads files or notes to the engine for async ingestion. The client SHALL exit immediately after a successful upload.
|
|
|
|
#### Scenario: Add a single file
|
|
- **WHEN** the user runs `kb add report.pdf`
|
|
- **THEN** the client SHALL upload the file via `POST /api/v1/jobs` (multipart), print "Queued: report.pdf", and exit
|
|
|
|
#### Scenario: Add a file with tags
|
|
- **WHEN** the user runs `kb add manual.pdf --tags car,maintenance`
|
|
- **THEN** the client SHALL include the tags in the multipart upload metadata
|
|
|
|
#### Scenario: Add a directory recursively
|
|
- **WHEN** the user runs `kb add ~/documents/ --recursive`
|
|
- **THEN** the client SHALL discover all supported files in the directory tree, upload each one sequentially, and print "Queued: N files"
|
|
|
|
#### Scenario: Add a text note
|
|
- **WHEN** the user runs `kb add --note "The server room is in building 3, floor 2"`
|
|
- **THEN** the client SHALL submit the note text via `POST /api/v1/jobs` (multipart with note field), print "Queued: note", and exit
|
|
|
|
#### Scenario: Add with JSON output
|
|
- **WHEN** the user runs `kb add report.pdf --format json`
|
|
- **THEN** the client SHALL output the JSON response from the engine including the job_id
|
|
|
|
#### Scenario: File not found
|
|
- **WHEN** the user runs `kb add nonexistent.pdf`
|
|
- **THEN** the client SHALL print an error and exit with a non-zero code without making any API call
|
|
|
|
#### Scenario: Upload failure
|
|
- **WHEN** the upload fails (network error, engine returns 4xx/5xx)
|
|
- **THEN** the client SHALL print the error and exit with a non-zero code
|
|
|
|
---
|
|
|
|
### Requirement: Jobs command
|
|
|
|
The client SHALL provide a `kb jobs` command to view the ingestion queue.
|
|
|
|
#### Scenario: List all jobs
|
|
- **WHEN** the user runs `kb jobs`
|
|
- **THEN** the client SHALL fetch `GET /api/v1/jobs` and display a table of recent jobs showing ID, filename, status, and timestamp
|
|
|
|
#### Scenario: Filter jobs by status
|
|
- **WHEN** the user runs `kb jobs --status failed`
|
|
- **THEN** the client SHALL pass the status filter and display only matching jobs
|
|
|
|
#### Scenario: Job details
|
|
- **WHEN** the user runs `kb jobs <id>`
|
|
- **THEN** the client SHALL fetch `GET /api/v1/jobs/{id}` and display full job details including error message (if failed), document_id (if done), and chunk count
|
|
|
|
---
|
|
|
|
### Requirement: Document management commands
|
|
|
|
The client SHALL provide commands to list, inspect, and remove documents.
|
|
|
|
#### Scenario: List documents
|
|
- **WHEN** the user runs `kb list`
|
|
- **THEN** the client SHALL fetch `GET /api/v1/documents` and display a table of documents with ID, title, type, tags, chunk count, and date
|
|
|
|
#### Scenario: List with filters
|
|
- **WHEN** the user runs `kb list --type pdf --tags manual`
|
|
- **THEN** the client SHALL pass filters as query parameters
|
|
|
|
#### Scenario: Document info
|
|
- **WHEN** the user runs `kb info <id>`
|
|
- **THEN** the client SHALL fetch `GET /api/v1/documents/{id}` and display full document details
|
|
|
|
#### Scenario: Remove a document
|
|
- **WHEN** the user runs `kb remove <id>`
|
|
- **THEN** the client SHALL prompt for confirmation, then send `DELETE /api/v1/documents/{id}` and display the result
|
|
|
|
#### Scenario: Remove with skip confirmation
|
|
- **WHEN** the user runs `kb remove <id> --yes`
|
|
- **THEN** the client SHALL skip the confirmation prompt
|
|
|
|
---
|
|
|
|
### Requirement: Tag management commands
|
|
|
|
The client SHALL provide commands to list and manage tags.
|
|
|
|
#### Scenario: List tags
|
|
- **WHEN** the user runs `kb tags`
|
|
- **THEN** the client SHALL fetch `GET /api/v1/tags` and display tags with document counts
|
|
|
|
#### Scenario: Add tags to a document
|
|
- **WHEN** the user runs `kb tag <id> --add manual,v2`
|
|
- **THEN** the client SHALL send `PUT /api/v1/documents/{id}/tags` with the add payload
|
|
|
|
#### Scenario: Remove tags from a document
|
|
- **WHEN** the user runs `kb tag <id> --remove draft`
|
|
- **THEN** the client SHALL send `PUT /api/v1/documents/{id}/tags` with the remove payload
|
|
|
|
---
|
|
|
|
### Requirement: Status command
|
|
|
|
The client SHALL provide a `kb status` command to display engine status.
|
|
|
|
#### Scenario: Display engine status
|
|
- **WHEN** the user runs `kb status`
|
|
- **THEN** the client SHALL fetch `GET /api/v1/status` and display model name, embedding dimensions, GPU info, document counts by type, total chunks, database size, and queue status
|
|
|
|
---
|
|
|
|
### Requirement: Global output format flag
|
|
|
|
All commands SHALL support a `--format` flag accepting `human` (default) or `json`. The default MAY be changed via the `default_format` config value.
|
|
|
|
#### Scenario: JSON output on any command
|
|
- **WHEN** the user passes `--format json` to any command
|
|
- **THEN** the client SHALL output the raw JSON response from the engine without human formatting
|
|
|
|
#### Scenario: Human output (default)
|
|
- **WHEN** the user runs any command without `--format`
|
|
- **THEN** the client SHALL format the response in a human-readable table or structured text output
|