wisp-agents 0.22.0 → 0.23.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/CHANGELOG.md +9 -1
- package/README.md +6 -6
- package/package.json +12 -2
- package/server/router.js +35 -20
- package/web/js/features/auto.js +1 -1
- package/web/js/features/runners.js +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,13 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
|
|
|
5
5
|
|
|
6
6
|
## [Unreleased]
|
|
7
7
|
|
|
8
|
+
## [0.23.0] - 2026-10-20
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- **Auto's Balanced goal runs frontier models.** When you have a frontier model installed and allowed (Opus, Codex's default, Gemini Argon, Grok 4.x), Balanced now picks it, at the harness's default or medium thinking, instead of Sonnet or Haiku. Best stays on frontier models at high or x-high, so the thinking level is what sets the two apart. Balanced steps down to an everyday model (Sonnet, never Haiku) only while every frontier model is at its limit, so the task still runs, or when you have none; small models' wins no longer pull Balanced to them after 20 outcomes. Cheap is unchanged. For models with the level in their name (Antigravity's `gemini-4-argon-low` / `-medium` / `-high`), the goal now picks the variant: Cheap low, Balanced medium, Best high, and the other variants count as the same model.
|
|
13
|
+
- **Guides on the website for what people search for.** Six new pages under [trywisp.dev/guides](https://trywisp.dev/guides/): [run Claude Code and Codex in parallel](https://trywisp.dev/guides/run-claude-code-and-codex-in-parallel.html), [run multiple Claude Code agents in parallel](https://trywisp.dev/guides/run-multiple-claude-code-agents-in-parallel.html), [run coding agents on multiple machines](https://trywisp.dev/guides/run-coding-agents-on-multiple-machines.html), [multi-agent coding](https://trywisp.dev/guides/multi-agent-coding.html), [Claude Code vs Codex on your own repo](https://trywisp.dev/guides/claude-code-vs-codex.html) and [run coding agents in the background](https://trywisp.dev/guides/run-coding-agents-in-the-background.html). Each answers its question in the first paragraph, shows the manual way with `git worktree` and `ssh`, then how wisp does it, and ends with FAQs (with `FAQPage` structured data). `scripts/guides.mjs` holds them; `scripts/site.mjs` renders them into the sitemap. The landing page's title, description and structured data now say *in parallel* and *on your other machines*, its FAQ answers both questions, and Guides is in the nav and footer of every page. The npm description and keywords match.
|
|
14
|
+
|
|
8
15
|
## [0.22.0] - 2026-10-20
|
|
9
16
|
|
|
10
17
|
### Added
|
|
@@ -413,7 +420,8 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and
|
|
|
413
420
|
- Session queue with follow-ups, answers to agent questions, terminal takeover and mark-as-done.
|
|
414
421
|
- Older turns are folded, with a floating collapse-all button and back-to-top.
|
|
415
422
|
|
|
416
|
-
[Unreleased]: https://github.com/M0xoo/wisp/compare/v0.
|
|
423
|
+
[Unreleased]: https://github.com/M0xoo/wisp/compare/v0.23.0...HEAD
|
|
424
|
+
[0.23.0]: https://github.com/M0xoo/wisp/compare/v0.22.0...v0.23.0
|
|
417
425
|
[0.22.0]: https://github.com/M0xoo/wisp/compare/v0.21.0...v0.22.0
|
|
418
426
|
[0.21.0]: https://github.com/M0xoo/wisp/compare/v0.20.0...v0.21.0
|
|
419
427
|
[0.20.0]: https://github.com/M0xoo/wisp/compare/v0.19.0...v0.20.0
|
package/README.md
CHANGED
|
@@ -56,7 +56,7 @@ From there you can **follow up**, **answer its questions**, **take it over** in
|
|
|
56
56
|
| 🤝 **Subagents** | Give the lead agent a team on other harnesses (e.g. Claude Code hands tests to Codex ×3). It delegates through a `delegate` tool; their edits land in its worktree. See [Subagents](#subagents). |
|
|
57
57
|
| ⏪ **Checkpoints & rollback** | Every turn is snapshotted first. Restore to before any turn, revert a single file, or re-run a command block from the presentation. |
|
|
58
58
|
| ⚖️ **Compare** | Run one task on two harnesses side by side, and keep the better run. |
|
|
59
|
-
| 🧾 **Recipes & triggers** | Saved prompts with `{params}` (`wisp run release 0.
|
|
59
|
+
| 🧾 **Recipes & triggers** | Saved prompts with `{params}` (`wisp run release 0.23.0`), run by hand, on a schedule, when CI fails, or when an issue is labelled. |
|
|
60
60
|
| 📊 **Usage** | Spend, success rate and questions per project and per harness · model. |
|
|
61
61
|
| 📱 **Phone** | Questions and finished tasks on ntfy or Telegram; answer from there, or start a task with `/new`. |
|
|
62
62
|
| 🔐 **Permission modes** | Choose **Plan** (read-only), **Edits** (file edits auto-accepted), or **Full auto** (no permission prompts, the default) for each launch. `Shift+Tab` in the prompt cycles modes. In Edits mode, anything the permissions block comes to you: Claude Code waits for **Allow / Always / Deny**, and the other harnesses show an **Allow & retry** card. |
|
|
@@ -85,7 +85,7 @@ brew install m0xoo/tap/wisp-agents # Homebrew: CLI and browser mode,
|
|
|
85
85
|
wisp "fix the flaky auth test"
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
-
The Homebrew formula lives in [M0xoo/homebrew-tap](https://github.com/M0xoo/homebrew-tap). `install.sh` honors `WISP_VERSION` to pin a release (`curl -fsSL https://trywisp.dev/install.sh | WISP_VERSION=0.
|
|
88
|
+
The Homebrew formula lives in [M0xoo/homebrew-tap](https://github.com/M0xoo/homebrew-tap). `install.sh` honors `WISP_VERSION` to pin a release (`curl -fsSL https://trywisp.dev/install.sh | WISP_VERSION=0.23.0 bash`).
|
|
89
89
|
|
|
90
90
|
From source:
|
|
91
91
|
|
|
@@ -135,7 +135,7 @@ wisp btw <id> "did you do X?" # ask on the side without interrupting the run
|
|
|
135
135
|
wisp stop <id>
|
|
136
136
|
wisp ship <id> [--draft] # commit, push and open a PR for a worktree task
|
|
137
137
|
wisp merge <id> # squash-merge its PR, fast-forward your local main
|
|
138
|
-
wisp run release 0.
|
|
138
|
+
wisp run release 0.23.0 # run a recipe; values fill its {params} (or version=0.23.0)
|
|
139
139
|
wisp recipes # list recipes
|
|
140
140
|
wisp usage [--days 7] # spend and outcomes
|
|
141
141
|
wisp mcp # MCP server for other agents and editors
|
|
@@ -304,7 +304,7 @@ If the harness has no system-prompt flag, prepend `systemPrompt` to the first pr
|
|
|
304
304
|
|
|
305
305
|
## Auto
|
|
306
306
|
|
|
307
|
-
**Auto** is the default harness: wisp picks the harness, model and thinking level for each task. Its "model" is a goal: **Balanced** (
|
|
307
|
+
**Auto** is the default harness: wisp picks the harness, model and thinking level for each task. Its "model" is a goal: **Balanced** (the default), **Cheap** or **Best**. Balanced and Best both run frontier models (Opus, not Sonnet or Haiku) when you have one installed and allowed; what sets them apart is how hard the agent thinks: Balanced runs at the harness's default or medium, Best at high or x-high. Cheap runs at low (or minimal) on whichever model does the job for least. A harness or model without levels runs at its default; for models with the level in their name (Antigravity's `gemini-4-argon-high`) the goal picks the variant the same way.
|
|
308
308
|
|
|
309
309
|
How it picks: every harness · model · thinking level you have installed is an option (`claude:opus:high`). For the kind of task (bug, feature, UI, tests, refactor, docs, release, question) Auto keeps an estimate of how often each option does it well. The estimate starts from a small wisp-bench pilot that ships with wisp (`server/router-priors.json`), then counts your own outcomes: merged PR (best), closed PR, 👍 / 👎, rollback, then how the run ended, less a bit for each follow-up you needed. It draws from each estimate (Thompson sampling), so options with little data now and then get a turn, and takes the best value for the goal after expected cost and time. A launch with `important: true` (API, SDK) gets the best-known option, with no trying. Options that keep failing a kind of task are left out of it. Thinking harder starts out a little more likely to work and costs more, and then your outcomes decide. A model's record at one level counts half at its other levels.
|
|
310
310
|
|
|
@@ -319,7 +319,7 @@ After the run, Auto checks the work before it lands in your queue:
|
|
|
319
319
|
3. **Repair**: new failures go back to the same agent (1 round by default, up to 2).
|
|
320
320
|
4. **Hand over**: still failing, or the run errored, so the task runs again on a stronger tier (small → everyday → frontier) in its own worktree, next to the first run.
|
|
321
321
|
|
|
322
|
-
A harness that says it's at its limit (session or usage limit, rate limit, no credit) isn't failing the task. Auto rests it until the limit resets, doesn't count the run against it, and moves the task to the best pick that can run now. Best always runs frontier models only
|
|
322
|
+
A harness that says it's at its limit (session or usage limit, rate limit, no credit) isn't failing the task. Auto rests it until the limit resets, doesn't count the run against it, and moves the task to the best pick that can run now. Best always runs frontier models only; it falls back to the strongest you have only when no frontier model is installed. Balanced runs on the strongest tier that can run now, whatever the record of the weaker models: frontier, or everyday (Sonnet, never Haiku) while every frontier model is at its limit or when you have none. The shipped estimates come from a small pilot, so they count for at most 4 tasks each.
|
|
323
323
|
5. **Best of two** (goal Best, off by default): two picks work side by side; tests decide, then a cheap model reads both diffs, and the better run is marked **Pick**.
|
|
324
324
|
|
|
325
325
|
Each step's outcome feeds the router: a test pass counts more than the agent's "done", needing a repair counts less, and losing a best-of-2 a little less again. Your own follow-up stops whatever Auto was about to do next. A launch on a machine is checked on that machine, where the files are. Settings → Auto turns each step on or off and sets the test command per project.
|
|
@@ -354,7 +354,7 @@ Before each turn, wisp snapshots the git working tree (pinned at `refs/wisp/chec
|
|
|
354
354
|
Prepare release {version}: update CHANGELOG, README and docs/, bump package.json, tag v{version}.
|
|
355
355
|
```
|
|
356
356
|
|
|
357
|
-
Make one from ⌘K → *Recipes*, or *Save as recipe…* on any card. A recipe may pin a project, harness, model and mode. Run it from ⌘K (*Run: Release*), from the Recipes view, or from a terminal: `wisp run release 0.
|
|
357
|
+
Make one from ⌘K → *Recipes*, or *Save as recipe…* on any card. A recipe may pin a project, harness, model and mode. Run it from ⌘K (*Run: Release*), from the Recipes view, or from a terminal: `wisp run release 0.23.0` fills the fields in order, `wisp run release version=0.23.0` by name.
|
|
358
358
|
|
|
359
359
|
**Triggers** launch sessions on their own while wisp is open (⌘K → *Triggers*):
|
|
360
360
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wisp-agents",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.23.0",
|
|
4
|
+
"description": "Run Claude Code, Codex, Cursor and other coding agents in parallel, in the background, on any of your machines. Skip the transcript, read the report.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"wisp": "bin/wisp.js",
|
|
@@ -31,7 +31,17 @@
|
|
|
31
31
|
"keywords": [
|
|
32
32
|
"claude",
|
|
33
33
|
"claude-code",
|
|
34
|
+
"codex",
|
|
35
|
+
"openai-codex",
|
|
36
|
+
"cursor",
|
|
37
|
+
"opencode",
|
|
34
38
|
"coding-agent",
|
|
39
|
+
"ai-agents",
|
|
40
|
+
"multi-agent",
|
|
41
|
+
"parallel",
|
|
42
|
+
"git-worktree",
|
|
43
|
+
"ssh",
|
|
44
|
+
"orchestration",
|
|
35
45
|
"ai",
|
|
36
46
|
"agents",
|
|
37
47
|
"cli",
|
package/server/router.js
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
//
|
|
3
3
|
// Every harness × model × thinking level the user has is an "arm" (claude:opus:high; no level is
|
|
4
4
|
// the harness's default). The goal picks the band of levels: Cheap runs low, Balanced the default
|
|
5
|
-
// or medium, Best high.
|
|
6
|
-
//
|
|
5
|
+
// or medium, Best high. Balanced and Best both run frontier models when you have one, so the
|
|
6
|
+
// level is what tells them apart. Within the band the levels are learned like models are, and a
|
|
7
|
+
// model's record at its other levels counts half. For each kind of task (bug, ui, docs, …) wisp
|
|
7
8
|
// keeps a Beta(wins, losses) estimate per arm, stacked from three sources: the shipped priors
|
|
8
9
|
// (./router-priors.json, from wisp-bench), the user's history on every kind of task, and the
|
|
9
10
|
// history on this kind. A launch draws a chance of success from each estimate (Thompson
|
|
@@ -27,13 +28,12 @@ const PRIORS = JSON.parse(fs.readFileSync(new URL('./router-priors.json', import
|
|
|
27
28
|
|
|
28
29
|
export const GOALS = {
|
|
29
30
|
cheap: { label: 'Cheap', value: 1, hint: 'Lowest cost that still gets it done' },
|
|
30
|
-
balanced: { label: 'Balanced', value: 5, hint: '
|
|
31
|
-
best: { label: 'Best', value: 50, hint: 'Frontier models
|
|
31
|
+
balanced: { label: 'Balanced', value: 5, hint: 'Frontier models at default or medium thinking' },
|
|
32
|
+
best: { label: 'Best', value: 50, hint: 'Frontier models at high thinking; cost only breaks ties' },
|
|
32
33
|
};
|
|
33
34
|
export const TYPES = ['bug', 'feature', 'ui', 'test', 'refactor', 'docs', 'release', 'question'];
|
|
34
35
|
const MINUTE_USD = 0.05; // what a minute of waiting costs you, in the utility
|
|
35
36
|
const PRIOR_CAP = 4; // shipped priors count as at most this many tasks, so your own soon outweigh them
|
|
36
|
-
const COLD_START = 20; // until Auto has this many of your outcomes, Balanced and Best stay on stronger tiers
|
|
37
37
|
const ALL_WEIGHT = 0.5; // your history on other kinds of task counts half
|
|
38
38
|
const HALF_LIFE_MS = 30 * 864e5; // models change: older outcomes fade
|
|
39
39
|
const NEW_ARM_SHARE = 0.25; // how often a new arm on probation may take an exploring slot
|
|
@@ -80,6 +80,17 @@ export const levelsFor = (efforts = [], goal = 'balanced') => {
|
|
|
80
80
|
const have = (BANDS[goal] || BANDS.balanced).filter((e) => e === '' || efforts.includes(e));
|
|
81
81
|
return have.length ? have : [''];
|
|
82
82
|
};
|
|
83
|
+
// Some harnesses bake the level into the model id (Antigravity's gemini-4-argon-high, no separate
|
|
84
|
+
// selector): there the goal picks among a model's variants the same way.
|
|
85
|
+
const SUFFIX = /-(minimal|low|medium|high|xhigh|max)$/;
|
|
86
|
+
const NAMED = { cheap: ['minimal', 'low'], balanced: ['medium'], best: ['high', 'xhigh', 'max'] };
|
|
87
|
+
const stemOf = (k) => baseOf(k).replace(SUFFIX, '');
|
|
88
|
+
function byNamedLevel(cands, goal) {
|
|
89
|
+
const want = NAMED[goal] || NAMED.balanced;
|
|
90
|
+
const named = (c) => !c.efforts.length && c.model.match(SUFFIX)?.[1];
|
|
91
|
+
const fits = new Set(cands.filter((c) => want.includes(named(c))).map((c) => stemOf(c.key)));
|
|
92
|
+
return cands.filter((c) => !named(c) || want.includes(named(c)) || !fits.has(stemOf(c.key)));
|
|
93
|
+
}
|
|
83
94
|
const effortLabel = (e) => ({ xhigh: 'X-High' })[e] || e.charAt(0).toUpperCase() + e.slice(1);
|
|
84
95
|
|
|
85
96
|
export const armKey = (agent, model = '', effort = '') => `${agent}:${model || ''}${effort ? `:${effort}` : ''}`;
|
|
@@ -99,10 +110,12 @@ export const baseOf = (k) => {
|
|
|
99
110
|
};
|
|
100
111
|
// Versions stripped: claude-sonnet-5-5 and claude-sonnet-5-6 are one family, and a new version
|
|
101
112
|
// starts from what the family already showed.
|
|
102
|
-
|
|
113
|
+
// A level in the id is the same model too: gemini-4-argon-high starts from what -medium showed.
|
|
114
|
+
const family = (k) => k.replace(SUFFIX, '').replace(/[-.]?\d+([.-]\d+)*/g, '');
|
|
103
115
|
|
|
104
116
|
// How strong a model is, roughly: 1 small/fast/free, 2 everyday, 3 frontier. Best runs on tier 3
|
|
105
|
-
// only,
|
|
117
|
+
// only, Balanced on the strongest tier that can run (frontier when you have one), and hand-overs
|
|
118
|
+
// step up a tier.
|
|
106
119
|
// The shipped priors come from a small pilot that flattered cheap models; tiers keep them honest.
|
|
107
120
|
const FRONTIER_DEFAULTS = new Set(['codex:']); // a harness whose default model is its frontier one
|
|
108
121
|
export function tierOf(key) {
|
|
@@ -259,34 +272,38 @@ export class Router {
|
|
|
259
272
|
// Pick an arm. agents: listAgents() of the place it runs. goal: cheap | balanced | best, which
|
|
260
273
|
// also sets the band of thinking levels (levelsFor).
|
|
261
274
|
// important: no exploring. exclude: arm keys already taken (compare, hand-overs): every level of
|
|
262
|
-
// that harness · model is out
|
|
263
|
-
// of a team must be a harness that can delegate. rng: for tests.
|
|
275
|
+
// that harness · model is out, and every variant of a model with its level in its id.
|
|
276
|
+
// needDelegate: the lead of a team must be a harness that can delegate. rng: for tests.
|
|
264
277
|
// scouted: { type, size } from the scout, which beats the keyword guess.
|
|
265
278
|
// minTier: only arms at least that strong (a hand-over steps up). Arms cooling down after a usage
|
|
266
279
|
// or rate limit are skipped while any other arm can run.
|
|
267
280
|
// Best runs frontier models only: if any is installed and allowed, Best never steps down a tier,
|
|
268
281
|
// even when they're all taken or at their limit (null then). With none installed, the strongest.
|
|
282
|
+
// Balanced runs frontier models too, whatever its record of the others (Sonnet or Haiku winning
|
|
283
|
+
// a few tasks doesn't make them the face of Auto), and steps down a tier only while every
|
|
284
|
+
// frontier model is taken or at its limit, so the task still runs.
|
|
269
285
|
choose({ prompt = '', attachments = 0, agents = [], goal = 'balanced', important = false, explore = true, exclude = [], needDelegate = false, allowed = null, scouted = null, minTier = 0, rng = Math.random } = {}) {
|
|
270
286
|
if (!this.synced) this.sync(agents);
|
|
287
|
+
if (!GOALS[goal]) goal = 'balanced';
|
|
271
288
|
const guess = classify(prompt, { attachments });
|
|
272
289
|
const type = scouted?.type || guess.type;
|
|
273
290
|
const size = scouted?.size || guess.size;
|
|
274
|
-
const V =
|
|
275
|
-
const out = new Set(exclude.map(
|
|
291
|
+
const V = GOALS[goal].value;
|
|
292
|
+
const out = new Set(exclude.map(stemOf));
|
|
276
293
|
const usable = candidates(agents, new Set(Object.keys(this.state.arms))).filter((c) => (!needDelegate || c.delegates) && (!allowed || allowed.includes(c.agent)));
|
|
277
294
|
const frontierOnly = goal === 'best' && usable.some((c) => tierOf(c.key) >= 3);
|
|
278
|
-
let arms = usable
|
|
279
|
-
.filter((c) => !
|
|
295
|
+
let arms = byNamedLevel(usable.filter((c) => !out.has(stemOf(c.key))), goal)
|
|
296
|
+
.filter((c) => !frontierOnly || tierOf(c.key) >= 3)
|
|
280
297
|
.flatMap((c) => levelsFor(c.efforts, goal).map((effort) => ({ ...c, key: armKey(c.agent, c.model, effort), effort, label: `${c.label}${effort ? ` · ${effortLabel(effort)}` : ''}`, base: c.key })))
|
|
281
298
|
.map((c) => ({ ...c, est: this.estimate(type, c.key), state: this.state.arms[c.base]?.state || 'new' }));
|
|
282
299
|
if (!arms.length) return null;
|
|
283
300
|
const free = arms.filter((x) => !this.cooling(x.key));
|
|
284
301
|
if (!free.length) return null; // everything allowed is at its limit: nothing to route to now
|
|
285
302
|
arms = free;
|
|
286
|
-
//
|
|
287
|
-
//
|
|
288
|
-
const
|
|
289
|
-
const floorTier = Math.max(minTier, goal === '
|
|
303
|
+
// Balanced and Best run on the strongest tier that can run now, whatever the record of the
|
|
304
|
+
// weaker ones. Cheap is left alone: that goal asked for cheap.
|
|
305
|
+
const top = Math.max(...arms.map((x) => tierOf(x.key)));
|
|
306
|
+
const floorTier = Math.max(minTier, goal === 'cheap' ? 0 : top);
|
|
290
307
|
for (let t = floorTier; t > 0; t--) {
|
|
291
308
|
const strong = arms.filter((x) => tierOf(x.key) >= t);
|
|
292
309
|
if (strong.length) {
|
|
@@ -323,7 +340,7 @@ export class Router {
|
|
|
323
340
|
key: pick.key,
|
|
324
341
|
label: pick.label,
|
|
325
342
|
route: {
|
|
326
|
-
goal
|
|
343
|
+
goal,
|
|
327
344
|
type,
|
|
328
345
|
size,
|
|
329
346
|
key: pick.key,
|
|
@@ -336,7 +353,6 @@ export class Router {
|
|
|
336
353
|
explored: byMean[0].key !== pick.key,
|
|
337
354
|
trying: pick.state === 'new',
|
|
338
355
|
tier: tierOf(pick.key),
|
|
339
|
-
...(cold && goal !== 'cheap' && goal !== 'best' && { coldStart: true }),
|
|
340
356
|
propensity: round(hits / 200),
|
|
341
357
|
alternatives: byMean.filter((x) => x.key !== pick.key).slice(0, 3).map((x) => ({ key: x.key, label: x.label, chance: round(x.est.mean), usd: round(x.est.usd) })),
|
|
342
358
|
at: this.now(),
|
|
@@ -453,7 +469,6 @@ export class Router {
|
|
|
453
469
|
return {
|
|
454
470
|
priors: { version: PRIORS.version, source: PRIORS.source },
|
|
455
471
|
learned: routes.filter((r) => r.r !== null).length,
|
|
456
|
-
coldStart: { needed: COLD_START, have: this.learned() },
|
|
457
472
|
routed: routes.length,
|
|
458
473
|
arms,
|
|
459
474
|
recent: routes.sort((p, q) => q.at - p.at).slice(0, 30).map((r) => ({ id: r.id, key: r.key, label: r.label, type: r.type, goal: r.goal, chance: r.chance, r: r.r, explored: r.explored, trying: r.trying, at: r.at, signals: r.signals })),
|
package/web/js/features/auto.js
CHANGED
|
@@ -25,7 +25,7 @@ export async function openRouter({ host } = {}) {
|
|
|
25
25
|
if (!r || !node.isConnected) return;
|
|
26
26
|
const arms = r.arms.filter((a) => a.state !== 'gone' || a.n);
|
|
27
27
|
$('.ro-body', node).innerHTML = `
|
|
28
|
-
<p class="hint">For each task Auto estimates every harness · model · thinking level’s chance of doing it well, from wisp-bench (${esc(r.priors.version)}) and then more and more from your own tasks: merged PRs, 👍 / 👎, rollbacks, follow-ups and how the run ended. It picks the best value for your goal (<b>${esc(AUTO_GOALS.find((g) => g.id === r.goal)?.label || '')}</b>), which also sets how hard it thinks: Cheap low, Balanced default or medium, Best high. Best
|
|
28
|
+
<p class="hint">For each task Auto estimates every harness · model · thinking level’s chance of doing it well, from wisp-bench (${esc(r.priors.version)}) and then more and more from your own tasks: merged PRs, 👍 / 👎, rollbacks, follow-ups and how the run ended. It picks the best value for your goal (<b>${esc(AUTO_GOALS.find((g) => g.id === r.goal)?.label || '')}</b>), which also sets how hard it thinks: Cheap low, Balanced default or medium, Best high. Balanced and Best run frontier models (Opus, not Sonnet or Haiku) when you have one; Balanced steps down to an everyday model only while every frontier one is at its limit. Now and then it tries an alternative so the estimates stay honest.</p>
|
|
29
29
|
<h4>Harness · model · thinking</h4>
|
|
30
30
|
<table class="us-table ro-table"><thead><tr><th></th><th>Works</th><th>Your tasks</th><th>~Cost</th><th>~Time</th><th></th></tr></thead><tbody>${arms
|
|
31
31
|
.map((a) => {
|
|
@@ -21,9 +21,9 @@ export const agentName = (id) => S.agents.find((a) => a.id === id)?.name || (id
|
|
|
21
21
|
// level per task. Its "models" are the goal it optimises for, which also sets the level band, so
|
|
22
22
|
// there are no thinking levels to pick here.
|
|
23
23
|
export const AUTO_GOALS = [
|
|
24
|
-
{ id: 'balanced', label: 'Balanced', hint: '
|
|
24
|
+
{ id: 'balanced', label: 'Balanced', hint: 'Frontier models · default or medium thinking' },
|
|
25
25
|
{ id: 'cheap', label: 'Cheap', hint: 'Lowest cost that still gets it done · low thinking' },
|
|
26
|
-
{ id: 'best', label: 'Best', hint: '
|
|
26
|
+
{ id: 'best', label: 'Best', hint: 'Frontier models · high thinking; cost only breaks ties' },
|
|
27
27
|
];
|
|
28
28
|
export const AUTO = { id: 'auto', name: 'Auto', available: true, delegates: true, models: AUTO_GOALS, efforts: [], hint: 'wisp picks the harness, model and thinking level from what worked before' };
|
|
29
29
|
|