@ferris1225/pi-subagents 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -239,6 +239,15 @@ currently unavailable vision selection is skipped immediately without rewriting
239
239
  it. A vision-flagged auto-fix chain keeps the flag for worker/re-review rounds
240
240
  because they may need to inspect the same images.
241
241
 
242
+ As a deterministic fallback, a brief that names an image file (an extension such
243
+ as `.png`, `.jpg`, `.webp`) or describes frontend/UI work — Vue/React/Svelte
244
+ pages, mockups, screenshots, page styling — is dispatched as
245
+ vision even without the flag: the model cannot be swapped mid-run, so a worker
246
+ that screenshots and visually verifies what it builds must start on a
247
+ vision-capable model. How do you verify which model ran? The live widget line,
248
+ dispatch result row, and `subagent_status` all show each run's effective model
249
+ id, and a selected→main handoff is labeled with its origin.
250
+
242
251
  ### Controlling and stopping
243
252
 
244
253
  Dispatch confirmations, tool result rows, and completion blocks all show the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ferris1225/pi-subagents",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
4
4
  "description": "Controllable background sub-agent threads for pi: specialized roles, capability-aware thinking, direct main-model fallback, auto-fix chains, and Git worktree isolation.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/dispatch.ts CHANGED
@@ -59,7 +59,7 @@ export { FORK_CONTINUATION_PROMPT, isWorktreeCapableAgent } from "./thread-lifec
59
59
  const NON_BLANK_TASK_OPTIONS = { minLength: 1, pattern: "\\S" } as const;
60
60
 
61
61
  const VISION_DESCRIPTION =
62
- "Set true when the task may require viewing images (screenshots, mockups, designs) — the configured vision model is used first, then model-level failures hand directly to the current main-window model";
62
+ "Set true when the task may require viewing images (screenshots, mockups, designs) — the configured vision model is used first, then model-level failures hand directly to the current main-window model. A task that names an image file or describes frontend/UI work (Vue/React, mockups, screenshots, page styling) is dispatched as vision automatically";
63
63
 
64
64
  const ISOLATION_DESCRIPTION =
65
65
  "Filesystem isolation: shared uses the caller's working tree; worktree creates a detached temporary Git worktree (write-capable agents, including worker and cleaner, only)";
@@ -95,6 +95,24 @@ export function defaultIsolationMode(mode: "single" | "parallel", agentName: str
95
95
  return mode === "parallel" && agentName === "worker" ? "worktree" : "shared";
96
96
  }
97
97
 
98
+ const IMAGE_FILE_PATTERN = /\.(?:png|jpe?g|webp|gif|bmp|tiff?|avif)\b/i;
99
+ /** Frontend/UI work: the agent may screenshot and visually verify what it
100
+ * builds, and the model cannot be swapped mid-run — vision must be on at
101
+ * spawn. `\bUI\b` stays case-sensitive so ordinary words never match. */
102
+ const FRONTEND_PATTERN = /\b(?:vue|react|svelte|angular|nuxt|next\.?js|vite|tailwind|screenshots?|mockups?|wireframes?|UI)\b|前端|界面|页面|样式|截图|设计稿/i;
103
+ const FRONTEND_FILE_PATTERN = /\.(?:vue|html?|css|svg)\b/i;
104
+
105
+ /** Deterministic vision fallback: a brief that names an image file or describes
106
+ * frontend/UI work is vision work even when the dispatcher forgot the flag —
107
+ * prompting alone cannot guarantee `vision: true`, and a non-vision model can
108
+ * neither see reference images nor visually verify what it builds. */
109
+ export function taskImpliesVision(task: string): boolean {
110
+ return IMAGE_FILE_PATTERN.test(task) || FRONTEND_FILE_PATTERN.test(task) || FRONTEND_PATTERN.test(task);
111
+ }
112
+
113
+ const wantsVision = (flag: boolean | undefined, task: string): boolean =>
114
+ flag === true || taskImpliesVision(task);
115
+
98
116
  const autoFixRootTails = new Map<string, Promise<void>>();
99
117
 
100
118
  async function canonicalAutoFixRoot(cwd: string): Promise<string> {
@@ -628,7 +646,7 @@ export function registerSubagentTool(pi: ExtensionAPI, runtime: SubagentRuntime)
628
646
  item.agent,
629
647
  item.task,
630
648
  item.cwd,
631
- item.vision === true,
649
+ wantsVision(item.vision, item.task),
632
650
  defaultIsolationMode("parallel", item.agent, item.isolation as IsolationMode | undefined),
633
651
  ));
634
652
  }
@@ -666,7 +684,7 @@ export function registerSubagentTool(pi: ExtensionAPI, runtime: SubagentRuntime)
666
684
  params.agent as string,
667
685
  params.task as string,
668
686
  params.cwd,
669
- params.vision === true,
687
+ wantsVision(params.vision, params.task as string),
670
688
  defaultIsolationMode("single", params.agent as string, params.isolation as IsolationMode | undefined),
671
689
  );
672
690
  if (result.exitCode !== -1) {
package/src/prompt.ts CHANGED
@@ -67,7 +67,7 @@ ${hasMultiple ? `- Run INDEPENDENT tasks in parallel: one subagent call with a \
67
67
  - Trust but verify: a sub-agent's summary describes intent, not outcome. Check the actual changes/results before reporting work done.
68
68
  ${hasExplore ? "- Treat `explore` findings as a retrieval index, never as sole proof for edits, deletion, security, compatibility, persistence, or dynamic reachability. Re-read load-bearing files before acting. An underpowered model can be false economy on complex dynamic, concurrent, migration, or security-sensitive code; use a stronger model or specialist there.\n" : ""}
69
69
  Vision tasks:
70
- - Judge whether a delegated task may require viewing images (frontend screenshots, mockups, design files, visual regression comparisons). If it might, pass \`vision: true\` in the subagent call and give the sub-agent the exact image paths — it reads them with its read tool.
70
+ - Judge whether a delegated task may require viewing images (frontend screenshots, mockups, design files, visual regression comparisons). If it might, pass \`vision: true\` in the subagent call and give the sub-agent the exact image paths — it reads them with its read tool. Naming an image file or describing frontend/UI work (Vue/React page, mockup, page styling) dispatches as vision automatically, but keep passing the flag for image work described without those signals.
71
71
  - \`vision: true\` runs the sub-agent on the vision-capable model configured in /subagents-setup; when none is configured it falls back to the main session's current model. Do not skip the flag because the agent's default model looks fast — a non-vision model cannot see the images.
72
72
 
73
73
  Result handoff (do not re-state):