@haoyiyin/9router 0.1.5 → 0.1.7

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
@@ -18,15 +18,15 @@ Environment variables are supported as a fallback: `ROUTER_API_BASE` / `ROUTER_A
18
18
 
19
19
  ## Combo models & thinking
20
20
 
21
- Combo models (`sub` / `free` / `main`, `owned_by: "combo"`) advertise no capabilities, so reasoning is off by default. If every upstream in a combo route supports thinking, opt in via `comboReasoning` in `~/.pi/agent/haoyiyin/9router.json`:
21
+ Combo models (`sub` / `free` / `main`, `owned_by: "combo"`) advertise no capabilities from the router, so their reasoning is decided by `comboReasoning` in `~/.pi/agent/haoyiyin/9router.json`. It defaults to **on** (assumes combo routes hit thinking-capable upstreams) with the standard `off..high` range. Opt out per machine with:
22
22
 
23
23
  ```json
24
24
  {
25
- "comboReasoning": true
25
+ "comboReasoning": false
26
26
  }
27
27
  ```
28
28
 
29
- `true` enables the default `off..high` range. To unlock `max`/`xhigh`, pass a custom `thinkingLevelMap` (keys: `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`; values: what gets sent to the router, `null` hides the level):
29
+ To unlock `max`/`xhigh`, pass a custom `thinkingLevelMap` (keys: `off`, `minimal`, `low`, `medium`, `high`, `xhigh`, `max`; values: what gets sent to the router, `null` hides the level):
30
30
 
31
31
  ```json
32
32
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@haoyiyin/9router",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "description": "Pi extension — 9Router provider (OpenCode Free oc/-free models + router models) + fetch/search/transcribe tools",
package/src/config.ts CHANGED
@@ -8,9 +8,10 @@ export interface RouterConfig {
8
8
  baseUrl: string;
9
9
  apiKey: string;
10
10
  /**
11
- * Opt-in to force reasoning:true onto combo models (`owned_by === "combo"`).
12
- * Combo models carry no capabilities from the router, so reasoning is normally
13
- * off. Set `true` for the default off..high range, or pass a custom
11
+ * Force reasoning:true onto combo models (`owned_by === "combo"`).
12
+ * Combo models carry no capabilities from the router, so this switch decides
13
+ * their reasoning status. Defaults to `true` (combo routes are assumed to hit
14
+ * thinking-capable upstreams); set `false` to opt out, or pass a custom
14
15
  * `thinkingLevelMap` to unlock max/xhigh on the combo routes.
15
16
  */
16
17
  comboReasoning?: boolean | { thinkingLevelMap?: Record<string, string | null> };
@@ -49,7 +50,7 @@ export function loadConfig(): RouterConfig {
49
50
 
50
51
  const apiKey = fileKey ?? process.env.ROUTER_API_KEY ?? "";
51
52
 
52
- return { baseUrl, apiKey, comboReasoning };
53
+ return { baseUrl, apiKey, comboReasoning: comboReasoning ?? true };
53
54
  }
54
55
 
55
56
  export function saveConfig(cfg: RouterConfig): void {
package/src/provider.ts CHANGED
@@ -15,8 +15,13 @@ import { fetchModelsDevIndex, lookupInIndex, routerBaseUrl, routerModels } from
15
15
  import { getZenFreeModels } from "./zen.ts";
16
16
  import { loadConfig, type RouterConfig } from "./config.ts";
17
17
 
18
- const DEFAULT_CONTEXT_WINDOW = 128_000;
19
- const DEFAULT_MAX_TOKENS = 16_384;
18
+ // ponytail: 128k was the old generic fallback; combo members bottom out at 200k,
19
+ // so the default now matches the smallest combo upstream. Raise again if the
20
+ // router ever exposes combo capabilities.contextWindow.
21
+ const DEFAULT_CONTEXT_WINDOW = 200_000;
22
+ // ponytail: 16k was the old generic fallback; combo members bottom out at 128k,
23
+ // so the default now matches the smallest combo upstream max output.
24
+ const DEFAULT_MAX_TOKENS = 128_000;
20
25
 
21
26
  const ZERO_COST = {
22
27
  input: 0,
@@ -85,8 +90,8 @@ function getThinkingFormat(model: RouterModel): "openai" | "deepseek" {
85
90
  /**
86
91
  * Derive pi's thinkingLevelMap from the router's advertised capabilities.
87
92
  * DeepSeek exposes low/high/max (mirrors pi's own deepseek catalog); openai-style
88
- * models keep the default off..high range, only hiding `off` when thinking cannot
89
- * be disabled. No map is returned when the backend does not declare reasoning.
93
+ * models expose off..max, hiding `off` when thinking cannot be disabled. No map
94
+ * is returned when the backend does not declare reasoning.
90
95
  */
91
96
  export function getThinkingLevelMap(
92
97
  model: RouterModel,
@@ -96,15 +101,19 @@ export function getThinkingLevelMap(
96
101
  if (cap.thinkingFormat === "deepseek") {
97
102
  return { minimal: null, low: "low", medium: null, high: "high", max: "max" };
98
103
  }
99
- if (cap.thinkingCanDisable === false) return { off: null };
100
- return undefined;
104
+ // openai-style: reasoning_effort takes the level name directly. Unlock
105
+ // xhigh/max, and hide off when thinking cannot be disabled.
106
+ return {
107
+ ...(cap.thinkingCanDisable === false ? { off: null } : {}),
108
+ xhigh: "xhigh",
109
+ max: "max",
110
+ };
101
111
  }
102
112
 
103
113
  /**
104
114
  * Combo models (`owned_by === "combo"`) carry no capabilities from the router, so
105
- * reasoning is normally off. Operators who guarantee their combo routes only hit
106
- * thinking-capable upstreams can opt in via `comboReasoning` in 9router.json:
107
- * `true` for the default off..high range, or an object with a custom
115
+ * their reasoning is decided by `comboReasoning` in 9router.json: default `true`
116
+ * (off..high range), `false` disables, or an object with a custom
108
117
  * `thinkingLevelMap` to unlock max/xhigh.
109
118
  */
110
119
  export function resolveComboOptIn(