@fastagent-sh/voicenote 0.18.6 → 0.18.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
@@ -113,7 +113,7 @@ Optional settings:
113
113
  "VOICENOTE_RECORD_DIR": "/Volumes/VTR6500/RECORD",
114
114
  "VOICENOTE_MAX_AGE_HOURS": "48",
115
115
  "VOICENOTE_PI_BIN": "pi",
116
- "VOICENOTE_PI_PROVIDER": "openai-codex,openai",
116
+ "VOICENOTE_PI_PROVIDER": "openai-codex",
117
117
  "VOICENOTE_PI_MODEL": "gpt-5.5",
118
118
  "VOICENOTE_PI_THINKING": "high",
119
119
  "VOICENOTE_PI_SUMMARY_TOOLS": "read,grep",
@@ -121,12 +121,16 @@ Optional settings:
121
121
  }
122
122
  ```
123
123
 
124
- `VOICENOTE_PI_PROVIDER` is a fallback chain, tried left to right. Credentials are
124
+ `VOICENOTE_PI_PROVIDER` is a fallback chain, tried left to right; it defaults to
125
+ `openai-codex` alone. Add the paid API path explicitly (`openai-codex,openai`) if
126
+ you keep an OpenAI key around. Credentials are
125
127
  resolved by `pi auth check` (covering OAuth, keys stored by `pi` → `/login`, and
126
128
  each provider's own API-key env var). A provider that deterministically cannot
127
129
  work — no credentials, or not a provider pi knows — is dropped from the chain,
128
130
  because its inevitable "No API key found" would replace the real error from the
129
- provider that actually failed. If that empties the chain, `vn run --mode notes`
131
+ provider that actually failed. When a chain still fails everywhere, the reported
132
+ error lists every provider's failure, so a fallback's missing key never hides why
133
+ the first provider broke. If pruning empties the chain, `vn run --mode notes`
130
134
  skips instead of paying for a transcript whose summary cannot happen.
131
135
  `vn doctor` prints the effective chain and the status of anything not ready.
132
136
 
package/README.zh-CN.md CHANGED
@@ -113,7 +113,7 @@ brew install ffmpeg
113
113
  "VOICENOTE_RECORD_DIR": "/Volumes/VTR6500/RECORD",
114
114
  "VOICENOTE_MAX_AGE_HOURS": "48",
115
115
  "VOICENOTE_PI_BIN": "pi",
116
- "VOICENOTE_PI_PROVIDER": "openai-codex,openai",
116
+ "VOICENOTE_PI_PROVIDER": "openai-codex",
117
117
  "VOICENOTE_PI_MODEL": "gpt-5.5",
118
118
  "VOICENOTE_PI_THINKING": "high",
119
119
  "VOICENOTE_PI_SUMMARY_TOOLS": "read,grep",
@@ -121,11 +121,13 @@ brew install ffmpeg
121
121
  }
122
122
  ```
123
123
 
124
- `VOICENOTE_PI_PROVIDER` 是从左到右尝试的回退链。凭证由 `pi auth check` 判定(覆盖
124
+ `VOICENOTE_PI_PROVIDER` 是从左到右尝试的回退链, 默认只有 `openai-codex`。如果你确实配了
125
+ OpenAI API key, 可以显式写成 `openai-codex,openai`。凭证由 `pi auth check` 判定(覆盖
125
126
  OAuth、`pi` → `/login` 存下的 key、以及各 provider 自己的 API key 环境变量)。
126
127
  确定不可能工作的 provider(没凭证, 或 pi 根本不认识这个名字)会被剔除 —— 否则
127
- 它必然抛出的 "No API key found" 会覆盖掉真正失败的那个 provider 的错误。若链因此
128
- 变空, `vn run --mode notes` 会直接跳过, 而不是花钱转写一个注定无法生成纪要的录音。
128
+ 它必然抛出的 "No API key found" 会覆盖掉真正失败的那个 provider 的错误。整条链都失败时,
129
+ 报错会列出每个 provider 的失败原因, 回退项缺 key 不会再掩盖第一个 provider 的真正错误。
130
+ 若剪枝后链变空, `vn run --mode notes` 会直接跳过, 而不是花钱转写一个注定无法生成纪要的录音。
129
131
  实际生效的链和非 ready 项的状态由 `vn doctor` 打印。
130
132
 
131
133
  ## 用法
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fastagent-sh/voicenote",
3
- "version": "0.18.6",
3
+ "version": "0.18.7",
4
4
  "description": "Voice recordings → diarized transcripts → integrated semantic Markdown notes. Currently optimized for the PHILIPS VTR6500 recorder, but the workflow is generic.",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/cli.ts CHANGED
@@ -13,7 +13,7 @@ import { fileURLToPath, pathToFileURL } from 'node:url'
13
13
  import { spawn, spawnSync } from 'node:child_process'
14
14
  import os from 'node:os'
15
15
 
16
- const VERSION = '0.18.6'
16
+ const VERSION = '0.18.7'
17
17
  const LAUNCH_AGENT_LABEL = 'sh.fastagent.voicenote'
18
18
  const LAUNCH_AGENT_LABEL_LEGACY = 'com.kid7st.voicenote' // pre-fastagent installs; cleaned up on install
19
19
  const TASK_NAME = 'VoiceNote' // Windows Task Scheduler name (mac uses LAUNCH_AGENT_LABEL)
@@ -1625,6 +1625,7 @@ async function chatCompleteViaPiCodex(opts: Omit<Parameters<typeof chatCompleteV
1625
1625
  if (!providers.length) throw new Error(noUsableProviderMessage())
1626
1626
  const maxAttempts = Math.max(1, Number(process.env.VOICENOTE_PI_RETRIES || 3))
1627
1627
  let lastError: any = null
1628
+ const failures: string[] = []
1628
1629
  for (const [idx, provider] of providers.entries()) {
1629
1630
  if (idx > 0) console.error(`pi provider fallback: trying ${provider} after ${providers[idx - 1]} failed: ${lastError?.message || lastError}`)
1630
1631
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
@@ -1641,7 +1642,14 @@ async function chatCompleteViaPiCodex(opts: Omit<Parameters<typeof chatCompleteV
1641
1642
  break // non-transient, or retries exhausted → fall back to next provider
1642
1643
  }
1643
1644
  }
1644
- }
1645
+ failures.push(`${provider}: ${String(lastError?.message || lastError).slice(0, 400)}`)
1646
+ }
1647
+ // Report EVERY provider's error, not just the chain's last one. The last link is
1648
+ // usually the fallback nobody signed into, so its "No API key found for openai"
1649
+ // buried the actual reason openai-codex failed (usage limit, expired token, 5xx)
1650
+ // in the notes stub and in the GUI — which then disagreed with a dashboard that
1651
+ // correctly showed ChatGPT as connected.
1652
+ if (failures.length > 1) throw new Error(`pi summary failed on every provider — ${failures.join(' | ')}`)
1645
1653
  throw lastError || new Error('pi provider fallback exhausted')
1646
1654
  }
1647
1655
 
package/src/piProvider.ts CHANGED
@@ -1,7 +1,12 @@
1
1
  // Which pi providers the summary chain tries. Credential *detection* lives in
2
2
  // cli.ts (it shells out to `pi auth check`); only the pure logic is here.
3
3
 
4
- export const DEFAULT_PI_PROVIDERS = ['openai-codex', 'openai']
4
+ // Only the free ChatGPT OAuth path by default. The paid OpenAI API fallback is
5
+ // opt-in (VOICENOTE_PI_PROVIDER='openai-codex,openai', or the GUI dropdown):
6
+ // shipping it in the default chain meant every codex failure was retried against
7
+ // a provider almost nobody has a key for, and that second failure was the one the
8
+ // user saw.
9
+ export const DEFAULT_PI_PROVIDERS = ['openai-codex']
5
10
 
6
11
  export function defaultPiModel(provider: string): string {
7
12
  return provider === 'deepseek' ? 'deepseek-v4-flash' : 'gpt-5.5'