152 lines
6.0 KiB
Markdown
152 lines
6.0 KiB
Markdown
# mp-ai-module-controller
|
|
|
|
Rust controller for starting a local `llama.cpp` server, asking it to map natural-language requests to known local actions, and dispatching exact-match Rust scripts. It supports both verbose action JSON and compact dictionary-coded outputs for hypersmall local models.
|
|
|
|
## Setup
|
|
|
|
```sh
|
|
cp .env.example .env
|
|
# edit LLAMA_MODEL_PATH in .env
|
|
cargo build
|
|
cargo run -- dictionary generate
|
|
git config core.hooksPath .githooks
|
|
```
|
|
|
|
The controller expects `llama-server` from `llama.cpp` to be installed. On this machine the planned binary is `/opt/homebrew/bin/llama-server`; if that path is not present, the controller falls back to `llama-server` on `PATH`.
|
|
|
|
## Commands
|
|
|
|
```sh
|
|
cargo run -- dictionary generate
|
|
cargo run -- serve
|
|
cargo run -- query "log hello from codex"
|
|
cargo run -- run logger --payload '{"message":"hello from direct dispatch"}'
|
|
cargo run -- run calculate --payload '{"expression":"2 + 2 * 3"}'
|
|
cargo run -- run to_slug --payload '{"text":"Hello, World!"}'
|
|
cargo run -- run write_note --payload '{"filename":"hello.txt","content":"hello"}'
|
|
scripts/precommit-check.sh
|
|
python3 scripts/generate_training_data.py --dry-run
|
|
scripts/deploy_training_data.sh
|
|
ENABLE_MIMIR_SDG=1 scripts/deploy_training_data.sh
|
|
```
|
|
|
|
`serve` starts:
|
|
|
|
```sh
|
|
llama-server --model "$LLAMA_MODEL_PATH" --host "$LLAMA_HOST" --port "$LLAMA_PORT"
|
|
```
|
|
|
|
Optional environment variables:
|
|
|
|
- `LLAMA_CONTEXT_SIZE`: appended as `--ctx-size`.
|
|
- `LLAMA_EXTRA_ARGS`: shell-split and appended to `llama-server`.
|
|
- `CONTROLLER_LOG_LEVEL`: tracing log level, default `info`.
|
|
- `ENABLE_MIMIR_SDG`: set to `1` for Mimir/Data Designer expansion during training-data deploy.
|
|
- `MIMIR_SDG_HOST`, `MIMIR_SDG_USER`, `MIMIR_SDG_KEY`, `MIMIR_SDG_MODEL_ALIAS`, `MIMIR_SDG_NUM_RECORDS`: SDG deploy overrides.
|
|
- `NVIDIA_API_KEY`: optional local Data Designer provider credential. Keep it in ignored `.env` only.
|
|
|
|
## Dictionary
|
|
|
|
Run `cargo run -- dictionary generate` to create:
|
|
|
|
- `dictionary/actions.jsonl`: canonical training dictionary, one action record per line.
|
|
- `dictionary/actions.index.json`: compact runtime lookup index.
|
|
- `dictionary/model.codebook.json`: static-plus-adaptive compact codebook.
|
|
- `dictionary/model.examples.jsonl`: hand-authored examples/templates for future synthetic-data tooling.
|
|
|
|
`dictionary/static-base.json` is the tracked static base dictionary. Generated metadata includes `dictionary_version`, `registry_checksum`, `static_base_checksum`, and `codebook_checksum`.
|
|
|
|
The runtime only dispatches exact `action_id` matches from `actions.index.json`. Aliases and examples are training hints, not executable ids. Compact model outputs must match the generated codebook version and checksum before expansion.
|
|
|
|
## LLM Response Contract
|
|
|
|
The local model must return compact JSON:
|
|
|
|
```json
|
|
{"action_id":"logger","payload":{"message":"hello"}}
|
|
```
|
|
|
|
It may also return compact codebook JSON:
|
|
|
|
```json
|
|
{"v":"1.0.0","c":"<codebook_checksum>","a":"A001","p":{"F001":"hello"}}
|
|
```
|
|
|
|
Malformed JSON, missing action codes, stale versions/checksums, aliases, and unknown action ids are rejected without running anything.
|
|
|
|
## Initial Script
|
|
|
|
The first registered script was `logger`. It writes JSONL records to `logs/controller-actions.jsonl`. Dispatch is detached: after the controller spawns the script process, it does not monitor completion.
|
|
|
|
## Action Suites
|
|
|
|
Math & Conversion:
|
|
|
|
- `calculate`: `{ "expression": "2 + 2 * 3" }`
|
|
- `convert_units`: `{ "value": 100, "from": "km", "to": "miles" }`
|
|
- `generate_uuid`: `{}`
|
|
- `random_number`: `{ "min": 1, "max": 100 }`
|
|
|
|
Text Utilities:
|
|
|
|
- `count_words`: `{ "text": "..." }`
|
|
- `to_slug`: `{ "text": "..." }`
|
|
- `hash_string`: `{ "text": "...", "algorithm": "sha256|md5|sha1" }`
|
|
- `truncate_text`: `{ "text": "...", "max_chars": 100 }`
|
|
|
|
File Operations:
|
|
|
|
- `write_note`: `{ "filename": "...", "content": "..." }`
|
|
- `append_to_file`: `{ "filename": "...", "content": "..." }`
|
|
- `read_file`: `{ "filename": "..." }`
|
|
- `delete_file`: `{ "filename": "..." }`
|
|
|
|
File operations are confined to project-local `notes/` and reject absolute paths or path traversal.
|
|
|
|
## CI And Hooks
|
|
|
|
The project includes:
|
|
|
|
- `.codex/environments/environment.toml` for Codex setup and run actions.
|
|
- `.gitea/workflows/ci.yml` for Gitea Actions.
|
|
- `.woodpecker.yml` for Woodpecker.
|
|
- `.githooks/pre-commit` for local pre-commit checks.
|
|
- `scripts/precommit-check.sh` as the shared validation entrypoint.
|
|
|
|
Enable the hook after cloning:
|
|
|
|
```sh
|
|
git config core.hooksPath .githooks
|
|
```
|
|
|
|
## SDG Bridge
|
|
|
|
`scripts/generate_training_data.py` generates instruction-format seed data from current dictionary artifacts. The default export root is `/Volumes/Zoe/custom-local-llm`.
|
|
|
|
Dry run:
|
|
|
|
```sh
|
|
python3 scripts/generate_training_data.py --dry-run
|
|
```
|
|
|
|
Local dataset generation:
|
|
|
|
```sh
|
|
python3 scripts/generate_training_data.py \
|
|
--dictionary-dir dictionary/ \
|
|
--output-dir /Volumes/Zoe/custom-local-llm/training-data/ \
|
|
--manifest /Volumes/Zoe/custom-local-llm/manifest.llm.json
|
|
```
|
|
|
|
Optional Mimir/Data Designer expansion is enabled only when `--sdg-host`, `--sdg-user`, and `--sdg-key` are supplied. The deploy helper turns this on with `ENABLE_MIMIR_SDG=1` and defaults to Mimir at `100.80.52.47`, user `aaron-pressey`, key `~/.ssh/silma_orson_ed25519`, model alias `nvidia-text`, and `1000` expanded rows. Override those with `MIMIR_SDG_HOST`, `MIMIR_SDG_USER`, `MIMIR_SDG_KEY`, `MIMIR_SDG_MODEL_ALIAS`, and `MIMIR_SDG_NUM_RECORDS`.
|
|
|
|
Remote expansion uses SSH to run Mimir's Data Designer CLI. It sources `/home/aaron-pressey/.config/home-grown-llm-data/data-designer.env`, uses the configured model alias, copies back `expanded.raw.jsonl`, and normalizes it to `expanded.jsonl`. The bridge does not start or restart Mimir inference services.
|
|
|
|
If remote expansion fails, the timestamped local seed dataset remains in place, `SDG_ERROR.txt` is written in that dataset directory, and the manifest entry is marked `generated_local_remote_failed`.
|
|
|
|
Woodpecker deploys a new enriched training-data export to Zoe on `main` pushes by running:
|
|
|
|
```sh
|
|
ENABLE_MIMIR_SDG=1 scripts/deploy_training_data.sh
|
|
```
|