linersh 0.5.3 → 0.5.5
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 +45 -16
- package/bin/liner.js +125 -1
- package/cli-update-docs/ABOUT.md +1 -1
- package/cli-update-docs/AI-HANDOFF.md +154 -0
- package/cli-update-docs/JOB-STORY-MIGRATION.md +1 -1
- package/cli-update-docs/JTBD-MASTER-PROMPT-ABOUT.md +1 -1
- package/cli-update-docs/LINER-MASTER.md +546 -0
- package/cli-update-docs/MIXTAPE-FORMAT.md +2 -2
- package/cli-update-docs/PLATFORM.md +2 -2
- package/cli-update-docs/README.md +5 -5
- package/cli-update-docs/SKILL.md +3 -3
- package/cli-update-docs/TUI-BACKLOG.md +12 -12
- package/dist/App.js +15 -7
- package/dist/App.js.map +1 -1
- package/dist/agents/detect.js +50 -8
- package/dist/agents/detect.js.map +1 -1
- package/dist/agents/models.js +34 -0
- package/dist/agents/models.js.map +1 -0
- package/dist/agents/runner.js +138 -10
- package/dist/agents/runner.js.map +1 -1
- package/dist/config.js +65 -14
- package/dist/config.js.map +1 -1
- package/dist/ipc.js +9 -0
- package/dist/ipc.js.map +1 -1
- package/dist/phases.js +2 -2
- package/dist/phases.js.map +1 -1
- package/dist/screens/AgentSetup.js +8 -3
- package/dist/screens/AgentSetup.js.map +1 -1
- package/dist/screens/CompileView.js +270 -16
- package/dist/screens/CompileView.js.map +1 -1
- package/dist/screens/JsSetup.js +77 -0
- package/dist/screens/JsSetup.js.map +1 -0
- package/dist/screens/PhaseRunner.js +87 -26
- package/dist/screens/PhaseRunner.js.map +1 -1
- package/dist/screens/ProcessManifest.js +1 -4
- package/dist/screens/ProcessManifest.js.map +1 -1
- package/dist/screens/ProjectHub.js +81 -26
- package/dist/screens/ProjectHub.js.map +1 -1
- package/dist/store.js.map +1 -1
- package/package.json +6 -5
|
@@ -29,7 +29,7 @@ Captured after comparing cli-writer-3 (v0.3 methodology, 15 sources) and cli-wri
|
|
|
29
29
|
### Compile-time fetcher chain
|
|
30
30
|
|
|
31
31
|
- **Wayback Machine as a fetcher tier between Playwright and the agent-summary fallback.** Cheap, no tokens, returns raw HTML the trafilatura extractor can use — full article instead of summary. Right move when richer fallback content matters for production-quality mixtapes. Discussed in the v6 session; deferred at curator's request because the agent-summary fallback is sufficient for current scope.
|
|
32
|
-
- **Per-source actions on compile failure** (`[d]` drop, `[o]` open in browser,
|
|
32
|
+
- **Per-source actions on compile failure** (`[d]` drop, `[o]` open in browser, maybe source-specific retry). The broad "install JS rendering" action now exists when Playwright Chromium is missing, and compile-result retry copy is clearer, but source-by-source recourse still needs a dedicated interaction model.
|
|
33
33
|
- **Failure detail capture.** When the web handler raises, capture the HTTP code, content-type, first ~500 bytes of body, and a category (`paywall`, `not_found`, `forbidden`, `js_required`, `tls`, `network`, `unknown`). Display on the failed source line. 80% of "why did this fail" questions resolved with no LLM call.
|
|
34
34
|
|
|
35
35
|
### Surface improvements
|
|
@@ -44,18 +44,9 @@ Captured after comparing cli-writer-3 (v0.3 methodology, 15 sources) and cli-wri
|
|
|
44
44
|
|
|
45
45
|
### Token cost surfaces (2026-05-27)
|
|
46
46
|
|
|
47
|
-
- **Remove the fake `$` cost figure from `ProcessManifest.tsx` (2026-05-28).** PhaseRunner's dollar figure was removed in 0.5.2 (see Done), but `ProcessManifest.tsx` still renders a `$` cost line aggregated from `.liner-runs/`. Same reasoning: subscription runs aren't metered API billing, so the dollar amount is invented while token counts are real. Drop the `$` line there too (or relabel as a clearly-marked estimate with a configurable rate) so the two surfaces don't diverge.
|
|
48
47
|
- **Cumulative token counter for the whole run.** Today the PhaseRunner shows live tokens for the current phase via the `tokens` event. There is no roll-up at the mixtape level — a curator finishes a 7-phase run with no idea what it cost in total. Aggregate token usage across all `.liner-runs/*.jsonl` entries for a project and surface a `Total tokens` line on the ProjectHub (or its own row in the ProcessManifest screen, which already aggregates similar data). Cheap because the aggregator already exists.
|
|
49
48
|
- **Pre-flight token estimate before kicking off a phase.** Before pressing Enter to run Phase 2 (or any agent-eligible phase), the user should see a "this phase typically costs ~X tokens" hint so they know roughly what they're committing to. Implementation idea: instrument the next several real runs to record actual per-phase token counts in `.liner-runs/`, then compute a rolling median per phase. After ~3–5 sample mixtapes, the median per-phase + per-mode (quick vs. methodology) becomes a useful baseline that ships with the package; later it should update dynamically from the user's own history. Open question: show the estimate per phase, or as a single "whole mixtape ≈ N tokens" number at wizard exit — both are useful, the latter is the bigger conversion lever. **Seed data exists:** a 2026-05-28 pass over the existing `.liner-runs` gives real per-phase medians on Opus (framing ~$0.35, candidates ~$3.2, evaluation ~$2.2, quality ~$1.1, synthesis ~$0.5, assembly ~$0.55; a full cycle ≈ 7–9M tokens, most of it cached reads). These can ship as the first baseline before per-user history kicks in.
|
|
50
49
|
|
|
51
|
-
### Per-phase model selection — cheaper model for the heavy phases (2026-05-28, recorded, not started)
|
|
52
|
-
|
|
53
|
-
- **Run the heavy phases on a cheaper model.** Token/cost analysis across the existing mixtapes (`.liner-runs/*.jsonl`, 2026-05-28) shows a full quick-mode cycle on `claude-opus-4-7[1m]` costs **~$6.50–9.00 at API rates**, and that **candidate discovery + evaluation are ~65% of it** (cli-writer-6: candidates $3.42, evaluation $2.61, quality $1.42, synthesis $0.63, assembly $0.61, framing $0.35). Dropping those two phases to **Sonnet** (and the OpenAI equivalent — e.g. a `gpt-5-mini`-class model — for Codex) would cut a cycle roughly **5×**, from ~$9 to ~$2, with the judgment-light fetch/triage work being the safest to downgrade. Framing / JTBD-clarify already fall back to Haiku. Implementation: a per-phase model map in the agent layer (`src/agents/`), passed through `buildArgs` as `--model` for Claude and the `-m`/model flag for Codex; keep the curator's default model for synthesis/quality where taste matters most, or expose the map in `~/.liner/config.yaml`. **Caveat:** the dollar figures are API-equivalent only — on a subscription the saving is rate-limit quota, not money. Decision deferred; recorded here.
|
|
54
|
-
|
|
55
|
-
### Agent unavailability needs a hard error, not a hang (2026-05-27)
|
|
56
|
-
|
|
57
|
-
- **Detect agent CLI auth/quota failure and fail loudly.** Observed 2026-05-27: starting a run with Codex while the underlying Codex subscription had expired produced a silent hang — the agent process was launched, didn't emit any stream events, didn't error out, and the TUI sat on the running spinner indefinitely. Same class of failure applies to revoked API keys, expired auth tokens, network blocked, model deprecated. The TUI needs a watchdog that, if no `assistant` / `tool_use` / `tokens` event arrives within ~15s of process start *and* stderr stays empty, surfaces a clear "couldn't reach <agent> — check auth/subscription" error with `[r] retry` and `[a] switch agent` actions. Likely fix is in the agent adapter (`src/agents/`), not the runner. Also worth a one-time pre-flight `--version` or `/whoami`-style call on agent selection so dead auth is caught before the curator commits to a phase.
|
|
58
|
-
|
|
59
50
|
### Slice 3 — agent integration polish
|
|
60
51
|
|
|
61
52
|
- **Background-banner concurrent runs.** Current architecture cancels the run when the user navigates away from PhaseRunner. If we want to support "leave the agent working while I edit elsewhere," we need to lift run state to app context and add a hub banner. Not blocking — pause-and-resume is a real product question, not just an implementation one.
|
|
@@ -101,17 +92,26 @@ The TUI work isn't blocking on these, but they shape what we build next.
|
|
|
101
92
|
- Methodology-mode validation: a planned side-by-side CLI vs. TUI design comparison.
|
|
102
93
|
- First library entry (Cowork synthesis → methodology-mode mixtape folder).
|
|
103
94
|
- MCP server scaffolding.
|
|
104
|
-
- **Marketing site: state the agent requirement up front (2026-05-28).** The landing page must make clear Liner drives the curation agent through the user's *own* Claude Code or Codex subscription — it doesn't bundle or pay for inference. This is both an honesty point (no surprise "why isn't it working" when a user has neither) and a positioning point (it rides the subscription they already pay for). Put it near the install/requirements section: "Bring your own agent — works with your Claude Code or Codex subscription." Lives in `marketing/site/`.
|
|
105
95
|
|
|
106
96
|
---
|
|
107
97
|
|
|
108
98
|
## Done
|
|
109
99
|
|
|
100
|
+
- 2026-05-29 — **Per-phase model selection (on by default) + model-rejection fallback.** Candidate discovery + evaluation (~65% of a cycle's tokens) now run on a cheaper model by default — Sonnet for Claude, `gpt-5-mini` for Codex — while framing/quality/synthesis/assembly stay on the agent's default. New `src/agents/models.ts` holds the default downgrade map + `modelForPhase()` resolver; `runner.ts` resolves the model in `runPhaseWithAgent` (config overrides win) and `buildArgs` emits `--model` for both agents on fresh runs only (a resumed session keeps its model). `UserConfig.models` (per-agent → phase → model id) added to `config.ts`; `writeConfig` now merges a partial over the on-disk config so changing the agent doesn't wipe overrides. Override in `~/.liner/config.yaml` under `models:`. **Maintenance:** Claude uses the `sonnet` alias (auto-tracks the latest Sonnet — no release needed on version bumps); only the concrete Codex id can rot. **Fallback:** `runAgentTask` was split into a delegating wrapper + `runAttempt`; if the agent rejects the model (detected via `looksLikeModelRejection`), it emits a warning naming the exact config fix and retries once on the agent's default model. Tests: `models.test.ts` (6), `runner.test.ts` (4 — detection heuristic), config round-trip/merge/malformed (3). **Caveat:** Codex's `gpt-5-mini` id is unverified against the user's Codex install — the fallback now covers a wrong id gracefully, and it's overridable in config.
|
|
101
|
+
- 2026-05-29 — **Agent-unavailability watchdog.** A launched-but-mute agent (signed out / expired subscription / deprecated model) used to hang the run spinner forever. `runAgentTask` now starts a 15s watchdog; if no stdout/stderr arrives in that window it emits a clear "no response from <agent> — check auth/subscription" raw event and SIGTERMs the child, so the run lands in the failed state (where retry / switch-agent already live). Any output clears it; cleared on close/error too. Constant `WATCHDOG_MS` in `runner.ts`. (Pre-flight `--version`/whoami check on agent selection still open as a nicer-but-optional follow-up.)
|
|
102
|
+
- 2026-05-29 — **Removed the invented `$` cost from `ProcessManifest.tsx`.** Dropped the Totals "Cost (USD)" row + the Runs-table "Cost" column/cell (and the "cost" mention in the empty-state copy). PhaseRunner's was already removed in 0.5.2; the two surfaces no longer diverge. Token counts stay (real); the `cost_usd` fields remain in the manifest types/Python output, just unrendered.
|
|
103
|
+
- 2026-05-29 — **Marketing site: agent requirement now stated up front.** The landing page (`marketing/site/src/pages/index.astro`) now makes the "bring your own agent" requirement explicit near install: a fourth Install-CTA requirements chip ("Bring your own agent — Claude Code or Codex", grid widened 3→2 cols for a 2×2) and an expanded FAQ answer ("Do I need my own AI subscription?…") that names Claude Code/Codex, states you need one to *build* a mixtape, and clarifies the finished mixtape is tool-agnostic. Honesty point (no surprise "why isn't it working") + positioning point (rides the subscription the user already pays for). Documented in `liner-private-docs/marketing-planning/page-outline.md` §9/§10 + decisions log.
|
|
110
104
|
- 2026-05-28 (0.5.3) — **`liner --version` reports the TUI version + version-pin drift killed.** The shim forwarded `--version` to the Python core, so it printed the core version (0.5.0) regardless of the installed npm package — confusing when verifying a publish. Now intercepts `--version`/`-v` in `bin/liner.js` and prints `liner <tui> (tui) · <core> (core)`. Also collapsed the three separately-edited version constants (package.json, Header.tsx, BootSplash.tsx) into one runtime read of package.json via `src/version.ts` — BootSplash had silently sat at 0.5.0 through the whole 0.5.2 cycle. Closes the old "Header version pin" hygiene item.
|
|
111
105
|
- 2026-05-28 (0.5.2) — **Fixed the hard API-400 crash on long/resumed agent runs.** A multi-turn phase (or any resume of a failed run) died with `400 … thinking blocks in the latest assistant message cannot be modified` once Claude Code auto-compacted a conversation with interleaved thinking on. Confirmed it was *not* resume-only: a fresh framing run hit it at ~26 turns, and resume then re-hit it instantly because it replays the corrupted message. Fix: spawn the agent with `MAX_THINKING_TOKENS=0` (verified empirically that this zeroes thinking blocks on claude 2.1.146 + opus-4-7), so the failure class can't occur. Supersedes the old "Resume + extended-thinking → API 400" item, which was mis-scoped as resume-only and low-priority. Change in `runner.ts` spawn env.
|
|
112
106
|
- 2026-05-28 (0.5.2) — **Isolated the methodology agent from the user's global environment.** The run log showed the spawned `claude` inheriting all the user's global MCP servers (Gmail, Drive, third-party connectors), plus Bash/Task — the `--allowedTools` whitelist is a no-op under `--dangerously-skip-permissions`. Added `--strict-mcp-config` (with no `--mcp-config` → zero MCP servers) so the agent no longer loads irrelevant connectors. *Still open:* hooks/auto-memory still load (didn't touch `--setting-sources` to avoid auth/behavior risk), and Bash/Task aren't hard-denied — a follow-up could add `--disallowedTools` or drop skip-permissions. Change in `runner.ts buildArgs`.
|
|
113
107
|
- 2026-05-28 (0.5.2) — **Fixed the mixtape browser (`TapeBrowser`) scrollback laddering + garbled selected row.** On a small terminal the project list rendered taller AND wider than the window, so arrow-key navigation reprinted the header on every keystroke (stacked `▶ liner` rows) and the selected row's highlight bled across wrapped lines. Fixes: a terminal-sized scrolling viewport (`maxRows = termRows − 12`, windowed around the selection, with `↑/↓ N more` indicators) so total height never exceeds the terminal; each row rendered as a single `wrap="truncate"` line with terminal-responsive column widths so rows never wrap; and `Header` subtitle set to `wrap="truncate"`. The alt-screen buffer alone couldn't fix this — it doesn't help when a single frame is taller than the viewport.
|
|
114
|
-
- 2026-05-
|
|
108
|
+
- 2026-05-31 (0.5.5) — **Completed Compile opens the existing result instead of rerunning.** If `MIXTAPE.md` is current, the hub marks Compile complete and pressing Enter opens a reconstructed compile-result screen from `MIXTAPE.md` + `sources/` instead of starting a fresh fetch. Recompile/retry is explicit with `r` from CompileView. This resolved the "Ready to use, but Enter compiles again" confusion from testing.
|
|
109
|
+
- 2026-05-31 (0.5.5) — **Partial compile is a usable ready state.** Compile now advances progress when it writes `MIXTAPE.md` with some failed sources, and the hub surfaces "Ready to use — compiled with warnings" with the source/warning counts. This keeps users from landing forever on "ready to compile" after they already have a finished artifact.
|
|
110
|
+
- 2026-05-31 (0.5.5) — **JS rendering setup is surfaced at onboarding and compile time.** Fresh installs get an optional JS setup screen after agent/model setup. Compile results that detect missing Playwright Chromium show "JS rendering needed", explain that headless Chromium is required for some pages, list the `liner setup-js --yes` action, show the ~150MB size, and bind `j` to install + retry.
|
|
111
|
+
- 2026-05-31 (0.5.5) — **Compile and done screens got internal scroll viewports.** The PhaseRunner final response and CompileView source list no longer depend on terminal scrollback in the alternate screen. ↑/↓ and pgup/pgdn scroll the relevant viewport; inspect mode keeps tool-call navigation distinct.
|
|
112
|
+
- 2026-05-31 (0.5.5) — **Web extraction handler crash fallback.** `trafilatura` exceptions now become soft failures with tag-stripped fallback content where possible instead of surfacing raw Python errors like `'NoneType' object is not subscriptable`. Covered in `tests/test_web_handler.py`.
|
|
113
|
+
- 2026-05-31 (0.5.5) — **`liner uninstall` added to the npm shim.** Removes `~/.liner`, npm `_npx`, and Playwright Chromium cache for clean-user testing. It intentionally leaves mixtape project folders alone.
|
|
114
|
+
- 2026-05-28 (0.5.2) — **Empirical test (Phase 7/8) removed from the driven flow.** Dropped `empirical` from `PhaseId`, `PHASE_TEMPLATES`, `PHASE_ORDER` (`TOTAL_STEPS` 11→10); removed the empirical branches in `phases.ts` and `PhaseRunner.tsx`. `everythingComplete()` collapses to `progress.step >= TOTAL_STEPS` and `coreMethodologyComplete` is gone — *compiled = complete*. The with-vs-without validation survives as methodology guidance in `cli-update-docs/LINER-MASTER.md` / skill docs, not a TUI phase.
|
|
115
115
|
- 2026-05-28 (0.5.2) — **ProjectHub redesigned into a single summary view.** Removed the dual focus-card / TOC `l` toggle. New `StatusBox` (Ready to use / In progress / Not started), an always-visible phase checklist, and a single HEADING/purple "next · …" call-to-action line. Importing a complete mixtape now lands here showing it's ready, never on a phase prompt.
|
|
116
116
|
- 2026-05-28 (0.5.2) — **Import screen auto-detects `.mixtape` files.** `ImportPrompt.tsx` rewritten: scans the cwd for `*.mixtape`, renders a selectable list with file sizes, `r` re-scans, `p` switches to path entry. Dropped the opaque "archive" label. Lands on the imported mixtape's hub (folder = `basename(path).replace(/\.mixtape$/,"")`) rather than the browser or a phase prompt. Import still doesn't auto-refetch.
|
|
117
117
|
- 2026-05-28 (0.5.2) — **Consistent quit-key convention: `q` quits from every screen, `esc` goes back.** Added `q` = `ink.exit()` to the gates, FramingConfirmReview, TapeDraftReview (guarded against text-input mode), PhaseRunner picking/done states; split `q`(quit)/`esc`(back) on CompileView + ProcessManifest. Gate2Review's quality-checks editor moved `q`→`k`. Text-input screens still rely on esc-then-quit / Ctrl-C since a bare `q` types into the field.
|
package/dist/App.js
CHANGED
|
@@ -15,9 +15,10 @@ import { Gate2Review } from "./screens/Gate2Review.js";
|
|
|
15
15
|
import { TapeDraftReview } from "./screens/TapeDraftReview.js";
|
|
16
16
|
import { ImportPrompt } from "./screens/ImportPrompt.js";
|
|
17
17
|
import { AgentSetup } from "./screens/AgentSetup.js";
|
|
18
|
+
import { JsSetup } from "./screens/JsSetup.js";
|
|
18
19
|
import { ProcessManifest } from "./screens/ProcessManifest.js";
|
|
19
20
|
import { BootSplash, shouldShowSplash } from "./screens/BootSplash.js";
|
|
20
|
-
import { configExists } from "./config.js";
|
|
21
|
+
import { configExists, readConfig } from "./config.js";
|
|
21
22
|
import { detectAgents } from "./agents/detect.js";
|
|
22
23
|
import { listProjects } from "./ipc.js";
|
|
23
24
|
import { existsSync, mkdirSync } from "node:fs";
|
|
@@ -27,13 +28,14 @@ const NOTIFICATION_MS = 3500;
|
|
|
27
28
|
const HISTORY_LIMIT = 10;
|
|
28
29
|
export function App() {
|
|
29
30
|
const baseDir = useRef(resolveBaseDir()).current;
|
|
30
|
-
// Decide what the user sees first.
|
|
31
|
+
// Decide what the user sees first. Four states, in priority order:
|
|
31
32
|
//
|
|
32
33
|
// 1. Agent setup — first launch on a machine with multiple agents
|
|
33
34
|
// installed AND no config file yet. Force a choice before the splash
|
|
34
35
|
// so the methodology phases don't hit the mid-phase picker.
|
|
35
|
-
// 2.
|
|
36
|
-
// 3.
|
|
36
|
+
// 2. JS setup — one-time onboarding for Playwright/Chromium support.
|
|
37
|
+
// 3. Splash — the normal greeting (cassette art + launch menu).
|
|
38
|
+
// 4. Browser — fallback when stdout isn't a TTY or LINER_NO_SPLASH is
|
|
37
39
|
// set (CI runs, narrow terminals).
|
|
38
40
|
//
|
|
39
41
|
// Single-agent installs skip step 1: there's nothing to pick. Repeat runs
|
|
@@ -136,6 +138,8 @@ function ScreenRoot({ screen }) {
|
|
|
136
138
|
return React.createElement(BootSplash, null);
|
|
137
139
|
case "agentSetup":
|
|
138
140
|
return React.createElement(AgentSetup, null);
|
|
141
|
+
case "jsSetup":
|
|
142
|
+
return React.createElement(JsSetup, null);
|
|
139
143
|
case "browser":
|
|
140
144
|
return React.createElement(TapeBrowser, null);
|
|
141
145
|
case "newProject":
|
|
@@ -165,7 +169,7 @@ function ScreenRoot({ screen }) {
|
|
|
165
169
|
case "sourceModal":
|
|
166
170
|
return (React.createElement(SourceModal, { tape: screen.tape, folder: screen.folder, editingIndex: screen.editingIndex }));
|
|
167
171
|
case "compile":
|
|
168
|
-
return React.createElement(CompileView, { tape: screen.tape, folder: screen.folder });
|
|
172
|
+
return (React.createElement(CompileView, { key: `${screen.folder}:${screen.showExisting ? "view" : "run"}`, tape: screen.tape, folder: screen.folder, showExisting: screen.showExisting }));
|
|
169
173
|
case "manifest":
|
|
170
174
|
return React.createElement(ProcessManifest, { tape: screen.tape, folder: screen.folder });
|
|
171
175
|
}
|
|
@@ -179,13 +183,17 @@ function resolveInitialScreen() {
|
|
|
179
183
|
// the user is probably in CI or scripting and just wants the browser.
|
|
180
184
|
if (!shouldShowSplash())
|
|
181
185
|
return { kind: "browser" };
|
|
182
|
-
// First-run setup only when we have a real choice to surface. One
|
|
183
|
-
// (or zero)
|
|
186
|
+
// First-run agent setup only when we have a real choice to surface. One
|
|
187
|
+
// agent (or zero) has nothing to pick, so go straight to the JS-rendering
|
|
188
|
+
// setup prompt.
|
|
184
189
|
if (!configExists()) {
|
|
185
190
|
const installed = detectAgents();
|
|
186
191
|
if (installed.length >= 2)
|
|
187
192
|
return { kind: "agentSetup" };
|
|
193
|
+
return { kind: "jsSetup" };
|
|
188
194
|
}
|
|
195
|
+
if (!readConfig().jsSetupPrompted)
|
|
196
|
+
return { kind: "jsSetup" };
|
|
189
197
|
return { kind: "splash" };
|
|
190
198
|
}
|
|
191
199
|
/**
|
package/dist/App.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"App.js","sourceRoot":"","sources":["../src/App.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,UAAU,EAA8B,MAAM,YAAY,CAAC;AACpE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"App.js","sourceRoot":"","sources":["../src/App.tsx"],"names":[],"mappings":"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"}
|
package/dist/agents/detect.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
2
3
|
import { existsSync } from "node:fs";
|
|
3
|
-
import {
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
import { join, dirname, basename } from "node:path";
|
|
4
6
|
import { fileURLToPath } from "node:url";
|
|
5
7
|
/**
|
|
6
8
|
* Resolve an agent binary path. Resolution order:
|
|
@@ -77,29 +79,69 @@ export function detectAgents() {
|
|
|
77
79
|
* 4. Walk up from `process.argv[1]` (legacy global-install case).
|
|
78
80
|
*/
|
|
79
81
|
export function resolveSkillPath() {
|
|
82
|
+
return resolveSkillPathWithDiagnostics().path;
|
|
83
|
+
}
|
|
84
|
+
export function resolveSkillPathWithDiagnostics() {
|
|
80
85
|
const env = process.env["LINER_SKILL_PATH"];
|
|
81
|
-
|
|
82
|
-
|
|
86
|
+
const envPath = env && env.trim() ? normalizeSkillPathInput(env.trim()) : null;
|
|
87
|
+
if (envPath && existsSync(join(envPath, "SKILL.md"))) {
|
|
88
|
+
return { path: envPath, envPath, searched: [join(envPath, "SKILL.md")] };
|
|
89
|
+
}
|
|
83
90
|
const candidates = ["cli-update-docs", "skills/curating-mixtapes"];
|
|
84
91
|
const moduleDir = dirname(fileURLToPath(import.meta.url));
|
|
92
|
+
const packageRoot = nearestPackageRoot(moduleDir);
|
|
85
93
|
const searchFromRoots = [
|
|
86
94
|
moduleDir,
|
|
95
|
+
packageRoot,
|
|
96
|
+
selfPackageRoot(),
|
|
87
97
|
process.cwd(),
|
|
88
98
|
dirname(process.argv[1] ?? ""),
|
|
89
|
-
].filter(Boolean);
|
|
99
|
+
].filter((root) => Boolean(root));
|
|
100
|
+
const searched = envPath ? [join(envPath, "SKILL.md")] : [];
|
|
90
101
|
for (const root of searchFromRoots) {
|
|
91
|
-
const hit = walkUp(root, candidates);
|
|
102
|
+
const hit = walkUp(root, candidates, searched);
|
|
92
103
|
if (hit)
|
|
93
|
-
return hit;
|
|
104
|
+
return { path: hit, envPath, searched };
|
|
105
|
+
}
|
|
106
|
+
return { path: null, envPath, searched };
|
|
107
|
+
}
|
|
108
|
+
function normalizeSkillPathInput(input) {
|
|
109
|
+
const expanded = input === "~"
|
|
110
|
+
? homedir()
|
|
111
|
+
: input.startsWith("~/")
|
|
112
|
+
? join(homedir(), input.slice(2))
|
|
113
|
+
: input;
|
|
114
|
+
return basename(expanded) === "SKILL.md" ? dirname(expanded) : expanded;
|
|
115
|
+
}
|
|
116
|
+
function nearestPackageRoot(start) {
|
|
117
|
+
let dir = start;
|
|
118
|
+
for (let i = 0; i < 12; i++) {
|
|
119
|
+
if (existsSync(join(dir, "package.json")))
|
|
120
|
+
return dir;
|
|
121
|
+
const parent = dirname(dir);
|
|
122
|
+
if (parent === dir)
|
|
123
|
+
return null;
|
|
124
|
+
dir = parent;
|
|
94
125
|
}
|
|
95
126
|
return null;
|
|
96
127
|
}
|
|
97
|
-
function
|
|
128
|
+
function selfPackageRoot() {
|
|
129
|
+
try {
|
|
130
|
+
const require = createRequire(import.meta.url);
|
|
131
|
+
return dirname(require.resolve("linersh/package.json"));
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function walkUp(start, candidates, searched) {
|
|
98
138
|
let dir = start;
|
|
99
139
|
for (let i = 0; i < 12; i++) {
|
|
100
140
|
for (const rel of candidates) {
|
|
101
141
|
const guess = join(dir, rel);
|
|
102
|
-
|
|
142
|
+
const skillFile = join(guess, "SKILL.md");
|
|
143
|
+
searched.push(skillFile);
|
|
144
|
+
if (existsSync(skillFile))
|
|
103
145
|
return guess;
|
|
104
146
|
}
|
|
105
147
|
const parent = dirname(dir);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/agents/detect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/agents/detect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Per-phase model selection.
|
|
2
|
+
//
|
|
3
|
+
// Candidate discovery + evaluation are ~65% of a cycle's token cost, and their
|
|
4
|
+
// work is fetch/triage-heavy rather than taste-heavy — so by default we run
|
|
5
|
+
// those two phases on a cheaper model (Sonnet for Claude, gpt-5-mini for
|
|
6
|
+
// Codex) and leave framing/quality/synthesis/assembly on the agent's own
|
|
7
|
+
// default, where curator judgment matters most. On a subscription the win is
|
|
8
|
+
// rate-limit quota, not dollars.
|
|
9
|
+
//
|
|
10
|
+
// A phase absent from the map runs on the agent's default model (no --model
|
|
11
|
+
// flag). Users override per agent + phase in ~/.liner/config.yaml — set a
|
|
12
|
+
// phase back to a flagship model to undo the downgrade.
|
|
13
|
+
// Default downgrades, applied unless the user overrides them in config. The
|
|
14
|
+
// values are the agent CLIs' own model identifiers/aliases: Claude accepts the
|
|
15
|
+
// `sonnet` alias; Codex takes a model id via -m/--model.
|
|
16
|
+
const DEFAULT_MODELS = {
|
|
17
|
+
claude: { candidates: "sonnet", evaluation: "sonnet" },
|
|
18
|
+
codex: { candidates: "gpt-5-mini", evaluation: "gpt-5-mini" },
|
|
19
|
+
};
|
|
20
|
+
export function defaultModelMap(agent) {
|
|
21
|
+
return DEFAULT_MODELS[agent] ?? {};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Resolve the model for a phase. A user override for that exact phase wins
|
|
25
|
+
* (including an empty string, read as "use the agent default"); otherwise the
|
|
26
|
+
* default downgrade map applies; otherwise undefined → the agent's own model.
|
|
27
|
+
*/
|
|
28
|
+
export function modelForPhase(agent, phaseId, overrides) {
|
|
29
|
+
if (overrides && Object.prototype.hasOwnProperty.call(overrides, phaseId)) {
|
|
30
|
+
return overrides[phaseId] || undefined;
|
|
31
|
+
}
|
|
32
|
+
return defaultModelMap(agent)[phaseId];
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=models.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../src/agents/models.ts"],"names":[],"mappings":"AAAA,6BAA6B;AAC7B,EAAE;AACF,+EAA+E;AAC/E,4EAA4E;AAC5E,yEAAyE;AACzE,yEAAyE;AACzE,6EAA6E;AAC7E,iCAAiC;AACjC,EAAE;AACF,4EAA4E;AAC5E,0EAA0E;AAC1E,wDAAwD;AAOxD,4EAA4E;AAC5E,+EAA+E;AAC/E,yDAAyD;AACzD,MAAM,cAAc,GAAmC;IACrD,MAAM,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE;IACtD,KAAK,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE;CAC9D,CAAC;AAEF,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,OAAO,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;AACrC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,KAAc,EACd,OAAgB,EAChB,SAAyB;IAEzB,IAAI,SAAS,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC;QAC1E,OAAO,SAAS,CAAC,OAAO,CAAC,IAAI,SAAS,CAAC;IACzC,CAAC;IACD,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC;AACzC,CAAC"}
|
package/dist/agents/runner.js
CHANGED
|
@@ -2,6 +2,12 @@ import { spawn } from "node:child_process";
|
|
|
2
2
|
import { buildPhasePrompt } from "./prompts.js";
|
|
3
3
|
import { LineBuffer, parseLine } from "./parsers.js";
|
|
4
4
|
import { closeRunLog, openRunLog } from "./run-log.js";
|
|
5
|
+
import { modelForPhase } from "./models.js";
|
|
6
|
+
import { readConfig } from "../config.js";
|
|
7
|
+
// How long to wait for the agent's first byte of output before declaring it
|
|
8
|
+
// unreachable. Generous enough to cover a cold CLI start + auth refresh, short
|
|
9
|
+
// enough that a dead subscription doesn't hang the TUI indefinitely.
|
|
10
|
+
const WATCHDOG_MS = 15_000;
|
|
5
11
|
/**
|
|
6
12
|
* Spawn the configured agent CLI with a phase-specific prompt. The agent's
|
|
7
13
|
* newline-delimited JSON stdout is parsed into AgentEvents so the PhaseRunner
|
|
@@ -17,11 +23,17 @@ export function runPhaseWithAgent(args) {
|
|
|
17
23
|
skillPath: args.skillPath,
|
|
18
24
|
tape: args.tape,
|
|
19
25
|
});
|
|
26
|
+
// Per-phase model: the built-in map downgrades the heavy phases, with the
|
|
27
|
+
// user's config.yaml overrides winning. The compile phase isn't an agent
|
|
28
|
+
// run; gates don't reach here either.
|
|
29
|
+
const overrides = readConfig().models?.[args.agent.id];
|
|
30
|
+
const model = modelForPhase(args.agent.id, args.phaseId, overrides);
|
|
20
31
|
return runAgentTask({
|
|
21
32
|
agent: args.agent,
|
|
22
33
|
project: args.project,
|
|
23
34
|
skillPath: args.skillPath,
|
|
24
35
|
prompt,
|
|
36
|
+
model,
|
|
25
37
|
taskLabel: args.phaseId,
|
|
26
38
|
resume: args.resume,
|
|
27
39
|
onEvent: args.onEvent,
|
|
@@ -35,9 +47,25 @@ export function runPhaseWithAgent(args) {
|
|
|
35
47
|
* text via the same callback interface.
|
|
36
48
|
*/
|
|
37
49
|
export function runAgentTask(args) {
|
|
50
|
+
// Delegating cancel: a model-rejection fallback re-spawns under the hood, so
|
|
51
|
+
// the handle's cancel must target whichever child is currently live.
|
|
52
|
+
let cancelCurrent = () => { };
|
|
53
|
+
const done = runAttempt(args, false, (c) => {
|
|
54
|
+
cancelCurrent = c;
|
|
55
|
+
});
|
|
56
|
+
return { cancel: () => cancelCurrent(), done };
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* One spawn attempt. On a model-rejection failure — and only on a fresh,
|
|
60
|
+
* model-pinned run — it warns the curator with the exact fix and retries once
|
|
61
|
+
* on the agent's default model, so a renamed/retired/mistyped model id
|
|
62
|
+
* degrades to "ran on the default" instead of a hard failure. `registerCancel`
|
|
63
|
+
* is re-invoked per attempt so the caller's cancel always hits the live child.
|
|
64
|
+
*/
|
|
65
|
+
function runAttempt(args, isModelFallback, registerCancel) {
|
|
38
66
|
const command = args.agent.bin;
|
|
39
67
|
const resume = args.resume === true;
|
|
40
|
-
const cliArgs = buildArgs(args.agent.id, args.project, args.skillPath, resume);
|
|
68
|
+
const cliArgs = buildArgs(args.agent.id, args.project, args.skillPath, resume, args.model);
|
|
41
69
|
const child = spawn(command, cliArgs, {
|
|
42
70
|
stdio: ["pipe", "pipe", "pipe"],
|
|
43
71
|
cwd: args.project,
|
|
@@ -55,6 +83,19 @@ export function runAgentTask(args) {
|
|
|
55
83
|
...(args.agent.id === "claude" ? { MAX_THINKING_TOKENS: "0" } : {}),
|
|
56
84
|
},
|
|
57
85
|
});
|
|
86
|
+
let cancelled = false;
|
|
87
|
+
registerCancel(() => {
|
|
88
|
+
cancelled = true;
|
|
89
|
+
if (!child.killed)
|
|
90
|
+
child.kill("SIGTERM");
|
|
91
|
+
});
|
|
92
|
+
// Accumulated tail of the agent's own output (stdout + stderr). Used only to
|
|
93
|
+
// recognize a model-rejection error for the fallback; capped so a long run
|
|
94
|
+
// doesn't retain the whole transcript.
|
|
95
|
+
let outputTail = "";
|
|
96
|
+
const noteForDetection = (chunk) => {
|
|
97
|
+
outputTail = (outputTail + chunk).slice(-4000);
|
|
98
|
+
};
|
|
58
99
|
// On resume, the previous session already contains the prompt + all prior
|
|
59
100
|
// tool-call results in context. Send a tiny continuation nudge instead of
|
|
60
101
|
// re-shipping the full prompt — that's the whole point of resume (cheaper,
|
|
@@ -72,10 +113,39 @@ export function runAgentTask(args) {
|
|
|
72
113
|
agent: args.agent.id,
|
|
73
114
|
resume,
|
|
74
115
|
});
|
|
116
|
+
// Agent-unavailability watchdog. A dead subscription / revoked auth / model
|
|
117
|
+
// deprecation can leave the agent process launched but mute — no stream
|
|
118
|
+
// events, no stderr, no exit — and the TUI would otherwise spin forever. If
|
|
119
|
+
// nothing comes back within the window, surface a clear error and kill the
|
|
120
|
+
// process so the run lands in the failed state (where retry / switch-agent
|
|
121
|
+
// live). Any output at all — stdout or stderr — clears the watchdog.
|
|
122
|
+
let sawOutput = false;
|
|
123
|
+
const watchdog = setTimeout(() => {
|
|
124
|
+
if (sawOutput || child.killed)
|
|
125
|
+
return;
|
|
126
|
+
const name = args.agent.id === "claude" ? "Claude Code" : "Codex";
|
|
127
|
+
args.onEvent({
|
|
128
|
+
kind: "raw",
|
|
129
|
+
text: `[liner] No response from ${name} after ${WATCHDOG_MS / 1000}s. ` +
|
|
130
|
+
`It may not be signed in, or its subscription/quota may be exhausted. ` +
|
|
131
|
+
`Try running \`${args.agent.id}\` on its own to check, then retry or switch agents.`,
|
|
132
|
+
});
|
|
133
|
+
log.write(JSON.stringify({ type: "_liner_watchdog_timeout", ms: WATCHDOG_MS }));
|
|
134
|
+
child.kill("SIGTERM");
|
|
135
|
+
}, WATCHDOG_MS);
|
|
136
|
+
watchdog.unref?.();
|
|
137
|
+
const noteOutput = () => {
|
|
138
|
+
if (sawOutput)
|
|
139
|
+
return;
|
|
140
|
+
sawOutput = true;
|
|
141
|
+
clearTimeout(watchdog);
|
|
142
|
+
};
|
|
75
143
|
const buffer = new LineBuffer();
|
|
76
144
|
if (child.stdout) {
|
|
77
145
|
child.stdout.setEncoding("utf8");
|
|
78
146
|
child.stdout.on("data", (chunk) => {
|
|
147
|
+
noteOutput();
|
|
148
|
+
noteForDetection(chunk);
|
|
79
149
|
const lines = buffer.push(chunk);
|
|
80
150
|
for (const line of lines) {
|
|
81
151
|
log.write(line);
|
|
@@ -89,6 +159,8 @@ export function runAgentTask(args) {
|
|
|
89
159
|
if (child.stderr) {
|
|
90
160
|
child.stderr.setEncoding("utf8");
|
|
91
161
|
child.stderr.on("data", (chunk) => {
|
|
162
|
+
noteOutput();
|
|
163
|
+
noteForDetection(chunk);
|
|
92
164
|
stderr += chunk;
|
|
93
165
|
// Surface stderr as raw events so users see install/auth hints inline.
|
|
94
166
|
for (const line of chunk.split("\n")) {
|
|
@@ -102,8 +174,9 @@ export function runAgentTask(args) {
|
|
|
102
174
|
}
|
|
103
175
|
});
|
|
104
176
|
}
|
|
105
|
-
|
|
177
|
+
return new Promise((resolve) => {
|
|
106
178
|
child.on("close", (code) => {
|
|
179
|
+
clearTimeout(watchdog);
|
|
107
180
|
// Flush any trailing partial line.
|
|
108
181
|
for (const line of buffer.flush()) {
|
|
109
182
|
log.write(line);
|
|
@@ -112,24 +185,41 @@ export function runAgentTask(args) {
|
|
|
112
185
|
}
|
|
113
186
|
}
|
|
114
187
|
closeRunLog(log, code, stderr.length);
|
|
188
|
+
// Model-rejection fallback. If a fresh, model-pinned run failed because
|
|
189
|
+
// the agent didn't recognize the model (renamed / retired / mistyped in
|
|
190
|
+
// config), warn the curator with the exact fix, then retry once on the
|
|
191
|
+
// agent's default model. Resumes, cancellations, and already-fallen-back
|
|
192
|
+
// runs are exempt — and we only claim "model rejected" when the output
|
|
193
|
+
// plausibly says so, so a real auth/quota failure surfaces normally.
|
|
194
|
+
if (code !== 0 &&
|
|
195
|
+
!cancelled &&
|
|
196
|
+
!resume &&
|
|
197
|
+
!isModelFallback &&
|
|
198
|
+
args.model &&
|
|
199
|
+
looksLikeModelRejection(outputTail, args.model)) {
|
|
200
|
+
args.onEvent({
|
|
201
|
+
kind: "raw",
|
|
202
|
+
text: `[liner] ${args.agent.name} rejected the model "${args.model}" set for ` +
|
|
203
|
+
`this phase — retrying on the default model. To fix: set ` +
|
|
204
|
+
`models.${args.agent.id}.${args.taskLabel} to a valid model id in ` +
|
|
205
|
+
`~/.liner/config.yaml, or remove it to keep the default.`,
|
|
206
|
+
});
|
|
207
|
+
log.write(JSON.stringify({ type: "_liner_model_fallback", model: args.model }));
|
|
208
|
+
resolve(runAttempt({ ...args, model: undefined }, true, registerCancel));
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
115
211
|
resolve({ code, stderr });
|
|
116
212
|
});
|
|
117
213
|
child.on("error", (e) => {
|
|
214
|
+
clearTimeout(watchdog);
|
|
118
215
|
args.onEvent({ kind: "raw", text: `[runner error] ${e.message}` });
|
|
119
216
|
log.write(JSON.stringify({ type: "_liner_error", message: e.message }));
|
|
120
217
|
closeRunLog(log, 1, stderr.length);
|
|
121
218
|
resolve({ code: 1, stderr: e.message });
|
|
122
219
|
});
|
|
123
220
|
});
|
|
124
|
-
return {
|
|
125
|
-
cancel: () => {
|
|
126
|
-
if (!child.killed)
|
|
127
|
-
child.kill("SIGTERM");
|
|
128
|
-
},
|
|
129
|
-
done,
|
|
130
|
-
};
|
|
131
221
|
}
|
|
132
|
-
function buildArgs(id, project, skillPath, resume) {
|
|
222
|
+
function buildArgs(id, project, skillPath, resume, model) {
|
|
133
223
|
if (id === "claude") {
|
|
134
224
|
// Stream-json requires --verbose. --include-partial-messages would give
|
|
135
225
|
// us mid-message chunking but the cost is ~10× more events; we let the
|
|
@@ -160,6 +250,11 @@ function buildArgs(id, project, skillPath, resume) {
|
|
|
160
250
|
"--allowedTools",
|
|
161
251
|
"Read Write Edit Glob Grep WebFetch",
|
|
162
252
|
];
|
|
253
|
+
// Apply the per-phase model on fresh runs only — a resumed session keeps
|
|
254
|
+
// the model it was started with, and `--model` alongside `--continue`
|
|
255
|
+
// wouldn't change the already-established conversation's model.
|
|
256
|
+
if (model && !resume)
|
|
257
|
+
base.push("--model", model);
|
|
163
258
|
if (resume)
|
|
164
259
|
base.push("--continue");
|
|
165
260
|
return base;
|
|
@@ -184,6 +279,7 @@ function buildArgs(id, project, skillPath, resume) {
|
|
|
184
279
|
"exec",
|
|
185
280
|
"--cd",
|
|
186
281
|
project,
|
|
282
|
+
...(model ? ["--model", model] : []),
|
|
187
283
|
"--add-dir",
|
|
188
284
|
skillPath,
|
|
189
285
|
"--skip-git-repo-check",
|
|
@@ -195,4 +291,36 @@ function buildArgs(id, project, skillPath, resume) {
|
|
|
195
291
|
}
|
|
196
292
|
return [];
|
|
197
293
|
}
|
|
294
|
+
/**
|
|
295
|
+
* Heuristic: did this failure come from the agent not recognizing the model?
|
|
296
|
+
* Matches the common "unknown/invalid model" phrasings both CLIs emit, plus
|
|
297
|
+
* the offending model id echoed next to an error token. Deliberately
|
|
298
|
+
* conservative — a false negative just means no auto-fallback (the normal
|
|
299
|
+
* error still surfaces); we only want to claim "model rejected" when it
|
|
300
|
+
* plausibly was, so genuine auth/quota failures aren't mislabeled.
|
|
301
|
+
*/
|
|
302
|
+
export function looksLikeModelRejection(output, model) {
|
|
303
|
+
const t = output.toLowerCase();
|
|
304
|
+
if (!t)
|
|
305
|
+
return false;
|
|
306
|
+
const phrases = [
|
|
307
|
+
"unknown model",
|
|
308
|
+
"invalid model",
|
|
309
|
+
"model not found",
|
|
310
|
+
"model_not_found",
|
|
311
|
+
"no such model",
|
|
312
|
+
"unrecognized model",
|
|
313
|
+
"unsupported model",
|
|
314
|
+
"not a valid model",
|
|
315
|
+
"model does not exist",
|
|
316
|
+
"is not a supported model",
|
|
317
|
+
];
|
|
318
|
+
if (phrases.some((p) => t.includes(p)))
|
|
319
|
+
return true;
|
|
320
|
+
// The model id echoed back alongside a generic error/invalid token.
|
|
321
|
+
const m = model.toLowerCase();
|
|
322
|
+
return (m.length > 0 &&
|
|
323
|
+
t.includes(m) &&
|
|
324
|
+
(t.includes("error") || t.includes("invalid") || t.includes("unknown") || t.includes("not found")));
|
|
325
|
+
}
|
|
198
326
|
//# sourceMappingURL=runner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/agents/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/agents/runner.ts"],"names":[],"mappings":"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"}
|