pullfrog 0.1.64 → 0.1.65

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/dist/internal.js CHANGED
@@ -185,7 +185,12 @@ var providers = {
185
185
  displayName: "O3",
186
186
  resolve: "openai/o3",
187
187
  effort: ["low", "medium", "high"],
188
- openRouterResolve: "openrouter/openai/o3"
188
+ openRouterResolve: "openrouter/openai/o3",
189
+ // OpenRouter publishes a reasoning TOGGLE for o3 where direct OpenAI
190
+ // publishes a ladder, so the route genuinely has no rungs. `[]` rather
191
+ // than omitting the field: an absent openRouterEffort falls through to
192
+ // `effort` and would send a rung this route rejects.
193
+ openRouterEffort: []
189
194
  }
190
195
  }
191
196
  }),
@@ -350,14 +355,19 @@ var providers = {
350
355
  effort: ["low", "medium", "high", "xhigh", "max"],
351
356
  openRouterResolve: "openrouter/anthropic/claude-opus-5",
352
357
  subagentModel: "claude-sonnet",
353
- // TEMPORARY — clear this when Zen serves opus again. Zen still LISTS
354
- // claude-opus-5 in /zen/v1/models, so the catalog test passes, but the
355
- // endpoint answers 503 `Upstream request failed: Endpoint is
356
- // unavailable.` (measured 5/5; claude-sonnet-5, claude-opus-4-8,
357
- // claude-haiku-4-5 and claude-fable-5 all 200 on the same key). opencode
358
- // retries the 503 above the AI SDK emitting no part.updated, so a run
359
- // just produces nothing until it is killed — metaideas/init logged six
360
- // zero-output failures from 2026-08-23. see wiki/opencode-silent-stall.md
358
+ // TEMPORARY — clear this ONLY when opus completes a run through opencode,
359
+ // never when the endpoint merely answers. Zen LISTS claude-opus-5 in
360
+ // /zen/v1/models, so the catalog test passes; on 2026-08-25 the endpoint
361
+ // itself answered 503 `Upstream request failed: Endpoint is unavailable.`
362
+ // (measured 5/5; claude-sonnet-5, claude-opus-4-8, claude-haiku-4-5 and
363
+ // claude-fable-5 all 200 on the same key). opencode retries above the AI
364
+ // SDK emitting no part.updated, so a run just produces nothing until it is
365
+ // killed — metaideas/init logged six zero-output failures from 2026-08-23.
366
+ // The 503 has since cleared and the model is STILL unusable: re-measured
367
+ // 2026-08-26, direct POST /zen/v1/messages is 10/10 200 at 1.3-4.1s while
368
+ // `opencode run --model opencode/claude-opus-5` on the same trivial prompt
369
+ // emitted nothing for 240s in CI. A raw-endpoint 200 is not runtime
370
+ // availability. see wiki/opencode-silent-stall.md
361
371
  fallback: "opencode/claude-sonnet"
362
372
  },
363
373
  "claude-sonnet": {
@@ -488,22 +498,139 @@ var providers = {
488
498
  }
489
499
  }
490
500
  }),
501
+ // OpenCode Go is a separate $10/mo subscription from Zen, served on its own
502
+ // base URL (`https://opencode.ai/zen/go/v1`) but authenticated with the SAME
503
+ // `OPENCODE_API_KEY`. it carries the open-weight coding models plus a couple
504
+ // of frontier ones, and 14 of the ids below are served ONLY here — Zen's
505
+ // `/v1/models` does not list glm-5.3*, qwen3.7/3.8-*, mimo-*, longcat-2.0,
506
+ // hy3 or muse-spark. so for a Go subscriber this provider is not a duplicate
507
+ // route to Zen, it is the only route to most of what they pay for.
508
+ // like `opencode` and `openrouter` this is a ROUTER, not a vendor: slugs and
509
+ // display names mirror the upstream brand tier, and the picker groups them
510
+ // under the upstream vendor.
491
511
  "opencode-go": provider({
492
512
  displayName: "OpenCode Go",
493
513
  envVars: ["OPENCODE_API_KEY"],
494
514
  models: {
515
+ // Z.ai — the plan's flagship coding family, and the only route the
516
+ // catalog offers to GLM at all.
517
+ glm: {
518
+ displayName: "GLM",
519
+ resolve: "opencode-go/glm-5.3",
520
+ effort: ["low", "high", "max"],
521
+ openRouterResolve: "openrouter/z-ai/glm-5.3",
522
+ preferred: true,
523
+ subagentModel: "glm-flash"
524
+ },
525
+ "glm-flash": {
526
+ displayName: "GLM Flash",
527
+ resolve: "opencode-go/glm-5.3-flash",
528
+ effort: ["low", "high", "max"],
529
+ openRouterResolve: "openrouter/z-ai/glm-5.3-flash"
530
+ },
531
+ // legacy alias — the slug pinned a version instead of a brand tier and
532
+ // was already resolving to 5.2 under a "GLM 5.2" label. folds forward to
533
+ // the tier slug; 16 repos and 9 accounts still hold it.
495
534
  "glm-5.1": {
496
535
  displayName: "GLM 5.2",
497
536
  resolve: "opencode-go/glm-5.2",
498
537
  effort: ["high", "max"],
499
538
  openRouterEffort: ["high", "xhigh"],
500
539
  openRouterResolve: "openrouter/z-ai/glm-5.2",
501
- preferred: true
540
+ fallback: "opencode-go/glm"
541
+ },
542
+ // Moonshot — parity with moonshotai/* and openrouter/*.
543
+ "kimi-k3": {
544
+ displayName: "Kimi K3",
545
+ resolve: "opencode-go/kimi-k3",
546
+ // Go publishes a single rung for K3 where the OpenRouter route
547
+ // publishes three, so every position lands on `max` here.
548
+ effort: ["max"],
549
+ openRouterEffort: ["low", "high", "max"],
550
+ openRouterResolve: "openrouter/moonshotai/kimi-k3",
551
+ subagentModel: "kimi-k2"
502
552
  },
503
553
  "kimi-k2": {
504
554
  displayName: "Kimi K2",
505
555
  resolve: "opencode-go/kimi-k2.7-code",
506
556
  openRouterResolve: "openrouter/moonshotai/kimi-k2.7-code"
557
+ },
558
+ // DeepSeek and Muse Spark are deliberately ABSENT even though Go serves
559
+ // them and prices DeepSeek Pro below Zen. each sits behind a per-workspace
560
+ // opt-in that is off by default — measured, the run dies with
561
+ // `RegionError` ("only available hosted in China") and `DataPolicyError`
562
+ // ("collects data used to improve its quality"). that toggle lives on the
563
+ // CUSTOMER's OpenCode workspace, so no change here can satisfy it, and a
564
+ // picker row that fails for almost everyone is worse than none. DeepSeek
565
+ // stays reachable ungated via `deepseek/*`, `opencode/*` and
566
+ // `openrouter/*`; both remain runnable by full specifier once opted in.
567
+ // Alibaba — new vendor family for the catalog; Zen serves neither tier.
568
+ "qwen-max": {
569
+ displayName: "Qwen Max",
570
+ resolve: "opencode-go/qwen3.8-max",
571
+ // both routes publish rungs, and they are different sets rather than
572
+ // different spellings of one — OpenRouter carries a `minimal` and a
573
+ // `high` the Go route does not.
574
+ effort: ["low", "medium", "xhigh"],
575
+ openRouterEffort: ["minimal", "low", "medium", "high", "xhigh"],
576
+ openRouterResolve: "openrouter/qwen/qwen3.8-max"
577
+ },
578
+ "qwen-plus": {
579
+ displayName: "Qwen Plus",
580
+ resolve: "opencode-go/qwen3.7-plus",
581
+ openRouterResolve: "openrouter/qwen/qwen3.7-plus"
582
+ },
583
+ // MiniMax — parity with opencode/* and openrouter/*; the m2 slug pins the
584
+ // line for DB stability while the resolve tracks the current m2.7.
585
+ "minimax-m3": {
586
+ displayName: "MiniMax M3",
587
+ resolve: "opencode-go/minimax-m3",
588
+ openRouterResolve: "openrouter/minimax/minimax-m3"
589
+ },
590
+ "minimax-m2.5": {
591
+ displayName: "MiniMax M2",
592
+ resolve: "opencode-go/minimax-m2.7",
593
+ openRouterResolve: "openrouter/minimax/minimax-m2.7"
594
+ },
595
+ // Xiaomi — Go-only; Zen serves the free `mimo-v2-pro-free` promo instead.
596
+ "mimo-pro": {
597
+ displayName: "MiMo Pro",
598
+ resolve: "opencode-go/mimo-v2.5-pro",
599
+ openRouterResolve: "openrouter/xiaomi/mimo-v2.5-pro"
600
+ },
601
+ // Meituan — Go-only.
602
+ longcat: {
603
+ displayName: "LongCat",
604
+ resolve: "opencode-go/longcat-2.0",
605
+ openRouterResolve: "openrouter/meituan/longcat-2.0"
606
+ },
607
+ // Tencent — Go-only, and the cheapest model on the plan by an order of
608
+ // magnitude (0.0175/0.0725). Hy3 succeeds the Hunyuan 2.0 line, so the
609
+ // generation is part of the product name the way Kimi K2/K3 is.
610
+ hy3: {
611
+ displayName: "Hy3",
612
+ resolve: "opencode-go/hy3",
613
+ effort: ["none", "low", "high"],
614
+ openRouterResolve: "openrouter/tencent/hy3"
615
+ },
616
+ // xAI and OpenAI — the two non-open models on the plan. same list price as
617
+ // Zen, but a Go subscription covers them where Zen meters them.
618
+ // Go is the only route that has retired grok-4.5 (models.dev marks
619
+ // `opencode-go/grok-4.5` deprecated while every other provider still
620
+ // serves it), so this alias LEADS `xai/grok` by a generation. a mirror
621
+ // that leads is safe; it is the trailing case that rots — see
622
+ // wiki/models-catalog.md on `opencode/kimi-k2`.
623
+ grok: {
624
+ displayName: "Grok",
625
+ resolve: "opencode-go/grok-4.6",
626
+ effort: ["low", "medium", "high", "xhigh"],
627
+ openRouterResolve: "openrouter/x-ai/grok-4.6"
628
+ },
629
+ "gpt-luna": {
630
+ displayName: "GPT Luna",
631
+ resolve: "opencode-go/gpt-5.6-luna",
632
+ effort: ["none", "low", "medium", "high", "xhigh", "max"],
633
+ openRouterResolve: "openrouter/openai/gpt-5.6-luna"
507
634
  }
508
635
  }
509
636
  }),
@@ -680,7 +807,6 @@ var providers = {
680
807
  "o4-mini": {
681
808
  displayName: "O4 Mini",
682
809
  resolve: "openrouter/openai/o4-mini",
683
- effort: ["low", "medium", "high"],
684
810
  openRouterResolve: "openrouter/openai/o4-mini"
685
811
  },
686
812
  "gemini-pro": {
package/dist/models.d.ts CHANGED
@@ -68,7 +68,8 @@ export interface ModelAlias {
68
68
  effort: readonly string[] | undefined;
69
69
  /** effort rungs on the OpenRouter route, when they differ from `effort` (the
70
70
  * DeepSeek/GLM top rung is `max` natively but `xhigh` via OpenRouter).
71
- * undefined falls back to `effort`. */
71
+ * undefined falls back to `effort`; `[]` says the OpenRouter route publishes
72
+ * no rungs at all, which undefined cannot express. */
72
73
  openRouterEffort: readonly string[] | undefined;
73
74
  /** hide from selectable lists (UI dropdowns, CLI pickers). does NOT affect
74
75
  * resolution — for that use `fallback`. used to keep a redundant alias out of
@@ -26,7 +26,7 @@ export type StoredPushDest = {
26
26
  * Lives here (not in `mcp/review.ts`) so `ToolState` — which caches
27
27
  * `Map<path, CommentableLines>` per checkout — does not pull the MCP server
28
28
  * graph into every consumer of run state (the action's main loop, agent
29
- * harnesses, cf-worker indexing).
29
+ * harnesses).
30
30
  */
31
31
  export type CommentableLines = {
32
32
  RIGHT: Set<number>;
@@ -1,3 +1,25 @@
1
+ /** shared sentence in the four `resolveSlug` routing-slug throws. */
2
+ export declare const BYOK_SLUG_MARKER = "env var is required when the model is set to";
3
+ /** shared sentence in the four `validate*Setup` throws. */
4
+ export declare const BYOK_CONFIG_MARKER = "selected but required configuration is missing:";
5
+ /**
6
+ * A BYOK provider setup is incomplete, at either of the two points that catch it:
7
+ * `resolveSlug` refusing a routing slug whose backing env var is unset, and the
8
+ * per-provider `validate*Setup` check that runs once the slug resolves. All eight
9
+ * messages already name what is missing, the remedy and a docs page, so the
10
+ * renderer passes them through rather than rewriting them. Before this they
11
+ * matched no branch at all, and `renderRunError` writes `errorMessage` to the job
12
+ * summary but not to the comment — so the answer existed on every one of these
13
+ * runs and the customer's PR comment read `Run failed.`
14
+ *
15
+ * Matched from character zero rather than searched anywhere in the text, because
16
+ * a match publishes the WHOLE message verbatim to a customer's PR and
17
+ * `errorMessage` is not always ours: `postRun` builds one out of a repo's own
18
+ * stop-hook output, which is arbitrary text the customer's script printed. A
19
+ * message that merely CONTAINS one of these errors is something quoting us, and
20
+ * passing it through would republish everything around it.
21
+ */
22
+ export declare function isByokSetupError(text: string): boolean;
1
23
  /**
2
24
  * marker for the distinct "run-context couldn't hand over your stored secrets"
3
25
  * body. surfaced verbatim by `runErrorRenderer` (same contract as
@@ -73,6 +95,14 @@ export declare function validateAgentApiKey(params: {
73
95
  * - org-disabled Claude subscription (#1072): `Your organization has
74
96
  * disabled Claude subscription access for Claude Code`, an entitlement
75
97
  * denial with its own remedy — see isClaudeSubscriptionDisabledError.
98
+ * - OpenAI rejected key: `Incorrect API key provided: sk-proj-***`, OpenAI's
99
+ * own wording for a revoked, rotated or wrong-project key. Absent from this
100
+ * list every such run rendered the generic one-line "Run failed." with no
101
+ * cause at all — measured on two accounts sitting at 100% failure, one of
102
+ * them for a week. Matched on the full phrase rather than "Incorrect API
103
+ * key" alone for the reason the markers above are phrased distinctively:
104
+ * this predicate short-circuits the whole rendering pipeline on a substring
105
+ * of arbitrary agent output.
76
106
  */
77
107
  export declare function isApiKeyAuthError(text: string): boolean;
78
108
  /**
@@ -1,3 +1,2 @@
1
- export declare const isCloudflareSandbox: boolean;
2
1
  export declare const isGitHubActions: boolean;
3
2
  export declare const isInsideDocker: boolean;
@@ -57,11 +57,7 @@ export declare function readLearningsFile(path: string): Promise<string | null>;
57
57
  * Best-effort: any failure is logged and does not affect the run's success
58
58
  * status. Skips the PATCH when the file is byte-trim-identical to its seed —
59
59
  * the agent didn't touch it, so writing the same content back would just
60
- * burn a `LearningsRevision` row and an API round-trip.
61
- *
62
- * `ctx.toolState.model` is forwarded so `LearningsRevision.model` keeps
63
- * populating; it powers the per-revision attribution badge in the UI
64
- * history view.
60
+ * burn an API round-trip.
65
61
  *
66
62
  * `learningsPersistAttempted` guards against double-execution between the
67
63
  * normal end-of-run path and the SIGINT/SIGTERM handler.
@@ -5,8 +5,8 @@
5
5
  * `action/internal/index.ts` without dragging the entire MCP type graph
6
6
  * along — `learnings.ts` imports `ToolContext` for its runtime helpers,
7
7
  * and pulling that into the SDK-facing `internal` barrel expands the
8
- * type graph reachable from root `tsc` and `cf-worker-indexing` to every
9
- * tool module under `action/mcp/`. keeping these helpers MCP-free is the
8
+ * type graph reachable from root `tsc` to every tool module under
9
+ * `action/mcp/`. keeping these helpers MCP-free is the
10
10
  * cheap structural fix.
11
11
  *
12
12
  * see `action/utils/learnings.ts` for the full learnings-file lifecycle.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pullfrog",
3
- "version": "0.1.64",
3
+ "version": "0.1.65",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "pullfrog": "dist/cli.mjs",