This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
# Builder Report — `pos ai hf` (Hugging Face Model Downloader)
|
||||
|
||||
**Date:** 2026-09-04
|
||||
**Status:** DONE
|
||||
|
||||
---
|
||||
|
||||
## TL;DR
|
||||
|
||||
Implemented `bin/pos-ai-hf` per the architecture report: a bash-only (curl + jq) Hugging Face model downloader with `search`/`download`/`list`/`remove` subcommands, `ai`-scope config (`HF_TOKEN`, `HF_DOWNLOAD_DIR`), auth headers, HTTP 429 retry, `curl -C -` resume, `.hf-meta` bookkeeping, and emoji output. Test harness (46 cases) green; all gates pass.
|
||||
|
||||
| Item | Status |
|
||||
|------|--------|
|
||||
| `bin/pos-ai-hf` created | [DONE] |
|
||||
| Syntax check | [DONE] |
|
||||
| Test harness (46/46) | [DONE] |
|
||||
| `make gen && make check` | [DONE] |
|
||||
| `make lint` (0 FAIL, 0 WARN) | [DONE] |
|
||||
| Doc updates (POS.md, AGENT_TODO.md) | [DONE] |
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Create `bin/pos-ai-hf` from template + implement full tool
|
||||
|
||||
Implemented the full tool: config loader (env-var precedence over `ai.env`), `hf_api`/`hf_repo_files`/`hf_search` helpers, `cmd_search`/`cmd_download`/`cmd_list`/`cmd_remove`, usage/help, error handling, `.hf-meta` writing. Deps guards (`curl`/`jq`) before `--help`. `# POS: ai hf —`, `# POS_FLAGS`, `# POS_DEPS`, `# POS_CONFIG`, `# POS_EXAMPLES` headers present. Chmod 100755.
|
||||
|
||||
[DONE]
|
||||
|
||||
## Step 2: Syntax check (`bash -n bin/pos-ai-hf`)
|
||||
|
||||
`bash -n bin/pos-ai-hf` → Syntax OK.
|
||||
|
||||
[DONE]
|
||||
|
||||
## Step 3: Test harness (`/tmp/opencode/hf-test/run-tests.sh`)
|
||||
|
||||
Stub-PATH harness: stub `curl` routes by URL pattern to fixtures; 46 numbered tests covering argument parsing (missing/unknown/invalid), download (single file via `-o`, whole repo, `--gguf`, `--branch`, `--output`), search, list, remove, config/token handling, and output format (emoji, size header/table formats).
|
||||
|
||||
Fixed two harness issues along the way: Test 22 size grep double-match (corrected regex), Test 40 token warning (empty config file + unset `HF_TOKEN` when the tool re-reads the config after `unset`).
|
||||
|
||||
**Result:** 46/46 green, exit 0.
|
||||
|
||||
[DONE]
|
||||
|
||||
## Step 4: Gates — `make gen && make check && make lint`
|
||||
|
||||
- `make gen` → `gen-docs: write OK`
|
||||
- `make check` → `check-sync: OK`
|
||||
- `make lint` → **0 FAIL, 0 WARN**
|
||||
- Initially hit 1 WARN (`pos-ai-hf: file not referenced in DOC/POS.md`); added the `bin/pos-ai-hf` reference in the `### ai` `**File:**` line — lint green after.
|
||||
|
||||
Verified generated output: docmap/tree/filetable updated in AGENT_Context, `completions/pos.bash` gained `ai-hf` flags and `ai` subcmd list, dispatch (`pos ai --help`, `pos help ai hf`, `pos ai hf --help`) all resolve.
|
||||
|
||||
[DONE]
|
||||
|
||||
## Step 5: Doc updates (POS.md, AGENT_TODO.md)
|
||||
|
||||
- `DOC/POS.md`: added `bin/pos-ai-hf` to the `### ai` `**File:**` line, and a dedicated `pos ai hf` command table + auth/rate-limit/resume detail block under the ai section.
|
||||
- `AGENT_TODO.md`: added a **Done** entry (newest-first, dated 2026-09-04) describing the tool, seam, config scope, verification.
|
||||
|
||||
[DONE]
|
||||
|
||||
---
|
||||
|
||||
## Verification Summary
|
||||
|
||||
- `bash -n bin/pos-ai-hf` — OK
|
||||
- `/tmp/opencode/hf-test/run-tests.sh` — 46/46 passed, exit 0
|
||||
- `make gen` — write OK
|
||||
- `make check` — OK
|
||||
- `make lint` — 0 FAIL, 0 WARN
|
||||
- `git status --short` — only intended changes: `AGENT_TODO.md`, generated `DOC/AGENT_Context_Project.md`, `DOC/POS.md`, `completions/pos.bash`, new `bin/pos-ai-hf`, new report file.
|
||||
|
||||
## Remaining Risks / Follow-up
|
||||
|
||||
- No live-network smoke against the real `huggingface.co` was run (stub-based tests only); real end-to-end (auth 401/403, 429, 404, jq parse error paths) should be exercised manually on a machine with network access before first real use.
|
||||
- `.hf-meta` uses a plain JSON object — no schema version field; acceptable for this scope.
|
||||
|
||||
## Handoff
|
||||
|
||||
Status: IMPLEMENTED
|
||||
|
||||
Approved scope:
|
||||
`bin/pos-ai-hf` (from `templates/pos-tool.sh`), `DOC/POS.md`, `AGENT_TODO.md`, test harness, report. No changes to `bin/pos-ai`, `bin/pos`, `preinstall.sh`, `lib/common.sh`, or INTERACTIVE_CMDS.
|
||||
|
||||
Changes made:
|
||||
New tool `bin/pos-ai-hf`; POS.md ai row + hf detail block; AGENT_TODO Done entry; generated docs/completions refreshed via `make gen`.
|
||||
|
||||
Files changed:
|
||||
`bin/pos-ai-hf` (new), `DOC/POS.md`, `AGENT_TODO.md`, `DOC/AGENT_Context_Project.md` (generated), `completions/pos.bash` (generated), `AgentsReport/builder/2026-09-04_hf-downloader-implementation.md` (new).
|
||||
|
||||
Verification performed:
|
||||
`bash -n`, 46/46 stub tests, `make gen && make check && make lint` (0 FAIL, 0 WARN).
|
||||
|
||||
Scope compliance:
|
||||
In-scope changes only; no out-of-scope changes.
|
||||
|
||||
Recommended next agent:
|
||||
Reviewer
|
||||
|
||||
Reason:
|
||||
Implementation complete and gates green; needs independent adversarial review before acceptance.
|
||||
@@ -0,0 +1,37 @@
|
||||
# Builder Report: `pos ai server` — llama.cpp Inference Server
|
||||
|
||||
## TL;DR
|
||||
|
||||
- **Status:** IMPLEMENTED
|
||||
- **Files created:** `bin/pos-ai-server`, `lib/ai-providers/llamacpp.sh`
|
||||
- **Files modified:** `bin/pos-ai` (4 case additions + POS_CONFIG header), `config/ai.env` (LLAMACPP_* docs), `DOC/POS.md` (ai server docs)
|
||||
- **Test harness:** `/tmp/opencode/llamacpp-test/run-tests.sh` — 87/87 passing
|
||||
- **Verification:** `make gen && make check && make lint` = 0 FAIL, 0 WARN
|
||||
|
||||
## Step 1: Create `bin/pos-ai-server`
|
||||
[DONE] — chmod 100755, syntax check passed, all conventions followed (set -euo pipefail, deps guards before --help, POS/POS_SUBCMDS/POS_FLAGS/POS_DEPS headers, common.sh source chain, err/log/warn/ok helpers, config seam guards)
|
||||
|
||||
## Step 2: Create `lib/ai-providers/llamacpp.sh`
|
||||
[DONE] — PROVIDER_CONFIG header present, 4-function contract (provider_name, provider_default_model, provider_generate, provider_models_list), syntax check passed
|
||||
|
||||
## Step 3: Modify `bin/pos-ai` — 4 case additions
|
||||
[DONE] — resolve_key: llamacpp returns 0 (no key needed), resolve_model: reads LLAMACPP_MODEL, cmd_providers: always "configured", require_key: llamacpp case (no key needed). POS_CONFIG header updated with LLAMACPP_* keys. Syntax check passed.
|
||||
|
||||
## Step 4: Modify `config/ai.env` — add LLAMACPP_* docs
|
||||
[DONE] — All 6 LLAMACPP_* config keys documented with defaults
|
||||
|
||||
## Step 5: Add POS.md documentation
|
||||
[DONE] — ai section updated with file references, server command table, flags, and config keys
|
||||
|
||||
## Step 6: Create test harness
|
||||
[DONE] — `/tmp/opencode/llamacpp-test/run-tests.sh` with 45 test groups (87 individual assertions), 0 failures. Tests cover: help/dispatch, error handling, start (config/arg/fallback), systemd unit generation (all fields), GPU detection (CPU/CUDA), model resolution (config/arg/relative/TTYPick), stop/status/models/logs, dry-run mode, flag overrides, POS headers, deps guards, pos-ai modifications.
|
||||
|
||||
## Step 7: Verification
|
||||
[DONE] — All gates pass:
|
||||
- `bash -n bin/pos-ai-server` — OK
|
||||
- `bash -n lib/ai-providers/llamacpp.sh` — OK
|
||||
- `bash -n bin/pos-ai` — OK
|
||||
- Test suite: 87/87 passed
|
||||
- `make gen` — OK
|
||||
- `make check` — OK
|
||||
- `make lint` — 0 FAIL, 0 WARN
|
||||
@@ -0,0 +1,78 @@
|
||||
# Builder Report: ytsync channel-handle fix
|
||||
|
||||
Date: 2026-09-04
|
||||
Agent: Builder
|
||||
Status: IMPLEMENTED
|
||||
|
||||
## TL;DR
|
||||
|
||||
- **Scope:** Single-file bug fix in `bin/pos-media-ytsync` — three changes (new helper + probe canonicalization + entry filter)
|
||||
- **Files changed:** `bin/pos-media-ytsync` (+ `DOC/AGENT_Context_Project.md` line-count bump from `make gen`)
|
||||
- **Baseline:** 12 PASS / 5 FAIL on unfixed script
|
||||
- **Result:** 32 PASS / 0 FAIL; `make gen`/`check`/`lint` all green; live dry-run shows 151 real videos; NOT committed
|
||||
- **Status: IMPLEMENTED**
|
||||
|
||||
## Step 1: Implement `canonical_channel_url()` helper
|
||||
|
||||
Insert after `classify_url()` (after line 176), before `sanitize_component()`.
|
||||
|
||||
[DONE]
|
||||
|
||||
## Step 2: Wire canonicalization into `run_probe()`
|
||||
|
||||
Add `url="$(canonical_channel_url "$url")"` after `local url="$1"` in `run_probe()`.
|
||||
|
||||
[DONE]
|
||||
|
||||
## Step 3: Add entry filter in `collect_entries()`
|
||||
|
||||
(a) Filter `.entries[]` to watchable URLs only
|
||||
(b) Guard single-object fallback with `_type == "video"` check
|
||||
|
||||
[DONE]
|
||||
|
||||
## Step 4: Syntax check
|
||||
|
||||
`bash -n bin/pos-media-ytsync`
|
||||
|
||||
[DONE]
|
||||
|
||||
## Step 5: Test harness — all assertions pass
|
||||
|
||||
Baseline was 12 PASS / 5 FAIL. After fix: **32 PASS / 0 FAIL** (Detective's 17 logical checks; harness counts 32 check calls — all green).
|
||||
|
||||
[DONE]
|
||||
|
||||
## Step 6: Gates — make gen && make check && make lint
|
||||
|
||||
`make gen` OK (regenerated `DOC/AGENT_Context_Project.md` — bumped hand-maintained line-count row for `bin/pos-media-ytsync` 1191 → 1213). `make check` OK. `make lint` → `0 FAIL, 0 WARN`.
|
||||
|
||||
[DONE]
|
||||
|
||||
## Step 7: Live dry-run — 3Blue1Brown sync
|
||||
|
||||
Seeded `/tmp/opencode/ytsync-live/` with a copy of the real registry (bare-handle URL). Ran:
|
||||
`YTSYNC_STATE_DIR=/tmp/opencode/ytsync-live YTSYNC_VIDEOS_DIR=/tmp/opencode/ytsync-live/vids bin/pos-media-ytsync sync --dry-run`
|
||||
|
||||
Output (exact match to expected):
|
||||
```
|
||||
Source : https://www.youtube.com/@3blue1brown ← stored URL unchanged (no migration)
|
||||
Resolved : 3Blue1Brown (channel · 151 videos)
|
||||
New : 151 would be downloaded (0 already present)
|
||||
But what is cross-entropy? | Compression is Intelligence Part 2.mp4
|
||||
Reinventing Entropy | Compression is Intelligence Part 1.mp4
|
||||
...
|
||||
… 146 more
|
||||
```
|
||||
Real video titles, not Videos/Live/Shorts tabs. Wrote nothing (archive empty, vids empty, registry unchanged).
|
||||
|
||||
[DONE]
|
||||
|
||||
## Step 8: One real download proof
|
||||
|
||||
Downloaded exactly one entry (`GlYgs6v2YfU` = "But what is cross-entropy?") standalone via
|
||||
`yt-dlp -o /tmp/opencode/ytsync-live/test.%(ext)s https://www.youtube.com/watch?v=GlYgs6v2YfU --no-playlist`.
|
||||
|
||||
yt-dlp resolved the video (not "[youtube] <id>: This video is unavailable"), pulled metadata, and began streaming (~154 MB / 31% of a 471 MiB file before the 180s tool timeout). Partial file cleaned up. This proves the dry-run probe's entry ids are valid and fetchable.
|
||||
|
||||
[DONE]
|
||||
Reference in New Issue
Block a user