Skip to content

v0.4.0 — batch + scale (SPEC-4) - #9

Merged
rz1989s merged 9 commits into
mainfrom
feat/v0.4.0-batch-and-scale
Jul 11, 2026
Merged

v0.4.0 — batch + scale (SPEC-4)#9
rz1989s merged 9 commits into
mainfrom
feat/v0.4.0-batch-and-scale

Conversation

@rz1989s

@rz1989s rz1989s commented Jul 11, 2026

Copy link
Copy Markdown
Member

Closes PRD gap #8 (batch handling). Third epic of the 5-epic roadmap (3/5 → 4/5 shipped).

What

  • Batch describe_image — additive image_paths: string[] param (alongside back-compat image_path). Parallel delegation via bounded concurrency, structured order-stable result, per-image resilience (a failed image is an [error: …] section, not a whole-batch fail). Hard cap MAX_BATCH_IMAGES=50. Single-image calls byte-for-byte back-compat (mode=delegate).
  • Parallel auto-delegation (paste auto mode) — serial loop → mapWithConcurrency; one batch-level AbortController replaces per-image timers (autoDelegateTimeoutMs is now the total batch budget).
  • lib/batch.ts — new pure mapWithConcurrency helper (bounded concurrency, order-preserving, reject-propagating).
  • Hint-mode path exposure (prerequisite fix)buildHintLine now lists the image paths + names the image_paths batch affordance, so a text-only primary can actually invoke describe_image (v0.3.x erased paths to markers, leaving the hint naming an uncallable tool).
  • Clipboard paste — documented, no new code — verified pi routes ctrl+vreadClipboardImage()/tmp/pi-clipboard-<uuid>.png → editor path (interactive-mode.js:2055), which our existing path-token pipeline already handles. Building a parallel clipboard-byte pipeline would be redundant (Israf). Regression guard test added.

Verified pi API facts (PLAN-4 §1)

  • Type.Array params render to the provider (proven by built-in edit tool, edit.js:19).
  • Gotcha: some models (Opus 4.6, GLM-5.1) send arrays as a JSON string — normalizeImagePaths coerces (mirrors edit.js:36 prepareEditArguments).
  • ctx.signal is defined during tool execution (PLAN-3 §1.3) — the batch uses it directly, no extra timeout.
  • Cache concurrent access is benign (PLAN-2 §1.2); dedup at the path boundary.

Tests (TDD)

286 pass, typecheck clean. T43–T53 added (28 new tests):

  • T43 batch basic (3 images, structured result in input order)
  • T44 ★ 10 images, batchConcurrency=5 → maxObserved ≥4 (conclusive parallelism gate, clears PRD "10+ images" bar)
  • T45 partial failure (bad image → [error: …], others succeed, isError false)
  • T46 all fail (isError true)
  • T47 single-image back-compat (mode=delegate, raw text)
  • T47b/c/d/e/f merge+dedup, stringified-array coercion, empty, over-cap, /vision batch-concurrency subcommand
  • T48 ★ paste auto parallel (4 images, maxObserved==4)
  • T49 ★ paste auto batch timeout (abort at ~1s, hint fallback lists paths)
  • T51 clipboard path regression guard
  • T52 ★ hint mode exposes paths + batch affordance
  • T53 v0.3.x regression gate (T1–T42 intact)
    • 12 mapWithConcurrency unit tests, 11 buildHintLine/buildBatchToolResult unit tests, 16 normalizeImagePaths unit tests, 11 batchConcurrency/MAX_BATCH_IMAGES config tests

Config

  • batchConcurrency (default 5, clamp 1–20) + /vision batch-concurrency subcommand + panel row.
  • autoDelegateTimeoutMs clamp min lowered 5000→1000ms (enables sane 1s batch budgets + makes batch-timeout testable). Minor SPEC-3 amendment, documented in the commit.
  • MAX_BATCH_IMAGES = 50 (code constant, not user-settable).

Pipeline

SPEC ✅ → PLAN ✅ → IMPL ✅ (TDD, one commit per feature) → EVAL (automated ✅; real-pi manual pending RECTOR) → PUBLISH (after merge → git tag v0.4.0 → CI auto-publish).

Specs: ~/Documents/secret/strategy/getpipher/vision/SPEC-4-batch-and-scale.md + PLAN-4-batch-and-scale.md.

Constraints met

  • Clean-room (no copied lines from pi-vision-tool/pi-paster).
  • No AI attribution in code/commits.
  • One commit per feature (9 commits).
  • pnpm typecheck && pnpm test:run green after every step.
  • jiti dual-module-instance: lib/batch.ts is stateless (no globalThis needed); no new shared module-level state.
  • Kitty keyboard protocol: unaffected (no handleInput changes).

rz1989s added 9 commits July 11, 2026 13:23
- auto mode: serial loop → mapWithConcurrency (bounded by batchConcurrency)
- one batch-level AbortController replaces per-image timers (autoDelegateTimeoutMs = total batch budget)
- autoDelegateOne takes the shared signal (no own controller)
- autoDelegateTimeoutMs clamp min lowered 5000→1000ms (enables sane 1s batch budgets + testable)
- T48/T49/T52 pass (parallel + batch timeout + hint paths)
- describe_image: +image_paths param (Type.Array), normalizeImagePaths (schema-tolerant: stringified-array coercion per edit.js:36 precedent)
- batch execute: mapWithConcurrency (bounded by batchConcurrency), per-image resilience (failed image → [error: …] section, not whole-batch fail), isError only when all fail
- single-image path byte-for-byte back-compat (mode=delegate, raw text)
- MAX_BATCH_IMAGES=50 hard cap + actionable errors (no paths, over cap)
- /vision batch-concurrency subcommand + panel row
- T43-T47f pass (batch basic, 10-image parallel, partial fail, all fail, back-compat, merge/dedup, stringified, empty, cap, subcommand)
- T51: /tmp/pi-clipboard-<uuid>.png path detected + markered + attached (guards the §3.3 finding that pi routes clipboard→tempfile→path)
- T53: regression gate (full suite green = T1-T52 intact)
- new 'Batch + scale (v0.4.0)' section: image_paths, parallel delegation, batchConcurrency, MAX_BATCH_IMAGES, structured result, parallel auto mode, hint-mode path exposure, clipboard-paste-via-path
- /vision batch-concurrency + /vision preview subcommand rows
- describe_image param table: +image_paths, optional image_path, details.batch traceability
…import (challenge step)

- export normalizeImagePaths from vision.ts + 16 unit tests (merge/dedup/stringified-array/invalid-JSON/whitespace/non-string/no-normalization edge cases)
- T44: tighten maxObserved assertion to >=4 (conclusively rules out serial execution, not just >=1)
- remove dead clearSharedState import from paste.ts
@rz1989s
rz1989s merged commit 3607f63 into main Jul 11, 2026
2 checks passed
@rz1989s
rz1989s deleted the feat/v0.4.0-batch-and-scale branch July 11, 2026 06:58
rz1989s added a commit that referenced this pull request Jul 11, 2026
v0.5.0: config + security defaults (final epic — gaps #9 + #10)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant