w-dispatch-ai 1.0.5 → 1.0.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 +4 -1
- package/dist/w-dispatch-ai.umd.js +2 -2
- package/dist/w-dispatch-ai.umd.js.map +1 -1
- package/docs/WDispatchAi.mjs.html +1 -1
- package/docs/adapters.mjs.html +1 -1
- package/docs/dfTimeoutMs.mjs.html +1 -1
- package/docs/dispatchAi.mjs.html +1 -1
- package/docs/dispatchAiFallback.mjs.html +71 -6
- package/docs/dispatchAiWkf.mjs.html +1 -1
- package/docs/dispatchAntigravity.mjs.html +1 -1
- package/docs/dispatchApiOpenaiCompat.mjs.html +1 -1
- package/docs/dispatchClaude.mjs.html +1 -1
- package/docs/dispatchCodex.mjs.html +1 -1
- package/docs/dispatchOpencode.mjs.html +1 -1
- package/docs/getCliArgs.mjs.html +1 -1
- package/docs/getErrorResult.mjs.html +1 -1
- package/docs/global.html +91 -11
- package/docs/index.html +1 -1
- package/docs/resolveProviders.mjs.html +1 -1
- package/docs/wkf_callAiWithFallback.mjs.html +13 -7
- package/docs/wkf_extractJsonLoose.mjs.html +1 -1
- package/docs/wkf_runFanout.mjs.html +11 -8
- package/docs/wkf_runFanoutPipeline.mjs.html +2 -2
- package/docs/wkf_runRolePipeline.mjs.html +1 -1
- package/package.json +1 -1
- package/src/dispatchAiFallback.mjs +70 -5
- package/src/wkf/callAiWithFallback.mjs +12 -6
- package/src/wkf/runFanout.mjs +10 -7
- package/src/wkf/runFanoutPipeline.mjs +1 -1
- package/test/unit-callAiWithFallback.test.mjs +15 -0
- package/test/unit-dispatchAiFallback.test.mjs +95 -0
- package/test/unit-dispatchAiWkf.test.mjs +8 -0
- package/test/unit-dispatchApiOpenaiCompat.test.mjs +28 -0
- package/test/unit-runFanout.test.mjs +46 -0
|
@@ -504,7 +504,7 @@ export default dispatchApiOpenaiCompat
|
|
|
504
504
|
<br class="clear">
|
|
505
505
|
|
|
506
506
|
<footer>
|
|
507
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026
|
|
507
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026 15:11:06 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
508
508
|
</footer>
|
|
509
509
|
|
|
510
510
|
<script>prettyPrint();</script>
|
|
@@ -190,7 +190,7 @@ export default dispatchClaude
|
|
|
190
190
|
<br class="clear">
|
|
191
191
|
|
|
192
192
|
<footer>
|
|
193
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026
|
|
193
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026 15:11:06 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
194
194
|
</footer>
|
|
195
195
|
|
|
196
196
|
<script>prettyPrint();</script>
|
|
@@ -191,7 +191,7 @@ export default dispatchCodex
|
|
|
191
191
|
<br class="clear">
|
|
192
192
|
|
|
193
193
|
<footer>
|
|
194
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026
|
|
194
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026 15:11:06 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
195
195
|
</footer>
|
|
196
196
|
|
|
197
197
|
<script>prettyPrint();</script>
|
|
@@ -260,7 +260,7 @@ export default dispatchOpencode
|
|
|
260
260
|
<br class="clear">
|
|
261
261
|
|
|
262
262
|
<footer>
|
|
263
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026
|
|
263
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026 15:11:06 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
264
264
|
</footer>
|
|
265
265
|
|
|
266
266
|
<script>prettyPrint();</script>
|
package/docs/getCliArgs.mjs.html
CHANGED
|
@@ -113,7 +113,7 @@ export default getCliArgs
|
|
|
113
113
|
<br class="clear">
|
|
114
114
|
|
|
115
115
|
<footer>
|
|
116
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026
|
|
116
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026 15:11:06 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
117
117
|
</footer>
|
|
118
118
|
|
|
119
119
|
<script>prettyPrint();</script>
|
|
@@ -102,7 +102,7 @@ export default getErrorResult
|
|
|
102
102
|
<br class="clear">
|
|
103
103
|
|
|
104
104
|
<footer>
|
|
105
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026
|
|
105
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026 15:11:06 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
106
106
|
</footer>
|
|
107
107
|
|
|
108
108
|
<script>prettyPrint();</script>
|
package/docs/global.html
CHANGED
|
@@ -376,7 +376,7 @@ console.log(dfTimeoutMs)
|
|
|
376
376
|
|
|
377
377
|
<dt class="tag-source">Source:</dt>
|
|
378
378
|
<dd class="tag-source"><ul class="dummy"><li>
|
|
379
|
-
<a href="wkf_callAiWithFallback.mjs.html">wkf/callAiWithFallback.mjs</a>, <a href="wkf_callAiWithFallback.mjs.html#
|
|
379
|
+
<a href="wkf_callAiWithFallback.mjs.html">wkf/callAiWithFallback.mjs</a>, <a href="wkf_callAiWithFallback.mjs.html#line70">line 70</a>
|
|
380
380
|
</li></ul></dd>
|
|
381
381
|
|
|
382
382
|
|
|
@@ -736,7 +736,7 @@ parse+check接進遞補層之validate——非法回覆視為該家失敗而
|
|
|
736
736
|
|
|
737
737
|
<dt class="tag-source">Source:</dt>
|
|
738
738
|
<dd class="tag-source"><ul class="dummy"><li>
|
|
739
|
-
<a href="wkf_callAiWithFallback.mjs.html">wkf/callAiWithFallback.mjs</a>, <a href="wkf_callAiWithFallback.mjs.html#
|
|
739
|
+
<a href="wkf_callAiWithFallback.mjs.html">wkf/callAiWithFallback.mjs</a>, <a href="wkf_callAiWithFallback.mjs.html#line144">line 144</a>
|
|
740
740
|
</li></ul></dd>
|
|
741
741
|
|
|
742
742
|
|
|
@@ -1250,6 +1250,46 @@ await test()
|
|
|
1250
1250
|
|
|
1251
1251
|
|
|
1252
1252
|
|
|
1253
|
+
<tr>
|
|
1254
|
+
|
|
1255
|
+
<td class="name"><code>minAttemptMs</code></td>
|
|
1256
|
+
|
|
1257
|
+
|
|
1258
|
+
<td class="type">
|
|
1259
|
+
|
|
1260
|
+
|
|
1261
|
+
<span class="param-type">Number</span>
|
|
1262
|
+
|
|
1263
|
+
|
|
1264
|
+
|
|
1265
|
+
|
|
1266
|
+
</td>
|
|
1267
|
+
|
|
1268
|
+
|
|
1269
|
+
<td class="attributes">
|
|
1270
|
+
|
|
1271
|
+
<optional><br>
|
|
1272
|
+
|
|
1273
|
+
|
|
1274
|
+
|
|
1275
|
+
|
|
1276
|
+
|
|
1277
|
+
</td>
|
|
1278
|
+
|
|
1279
|
+
|
|
1280
|
+
|
|
1281
|
+
<td class="default">
|
|
1282
|
+
|
|
1283
|
+
<code>20000</code>
|
|
1284
|
+
|
|
1285
|
+
</td>
|
|
1286
|
+
|
|
1287
|
+
|
|
1288
|
+
<td class="description last"><p>輸入搭配budgetMs之開工門檻毫秒正整數,剩餘預算低於此值即不再開工,預設20000</p></td>
|
|
1289
|
+
</tr>
|
|
1290
|
+
|
|
1291
|
+
|
|
1292
|
+
|
|
1253
1293
|
<tr>
|
|
1254
1294
|
|
|
1255
1295
|
<td class="name"><code>maxRetries</code></td>
|
|
@@ -1405,7 +1445,7 @@ await test()
|
|
|
1405
1445
|
</td>
|
|
1406
1446
|
|
|
1407
1447
|
|
|
1408
|
-
<td class="description last"><p>輸入遞補層事件回調函數,預設null</p></td>
|
|
1448
|
+
<td class="description last"><p>輸入遞補層事件回調函數,預設null。除上列外之其餘鍵(retryDelayMs、maxBuffer、onStdout等)亦一律原樣轉傳dispatchAiFallback</p></td>
|
|
1409
1449
|
</tr>
|
|
1410
1450
|
|
|
1411
1451
|
|
|
@@ -2238,7 +2278,7 @@ providers陣列順序即優先序,排前面的先用;
|
|
|
2238
2278
|
|
|
2239
2279
|
<dt class="tag-source">Source:</dt>
|
|
2240
2280
|
<dd class="tag-source"><ul class="dummy"><li>
|
|
2241
|
-
<a href="dispatchAiFallback.mjs.html">dispatchAiFallback.mjs</a>, <a href="dispatchAiFallback.mjs.html#
|
|
2281
|
+
<a href="dispatchAiFallback.mjs.html">dispatchAiFallback.mjs</a>, <a href="dispatchAiFallback.mjs.html#line199">line 199</a>
|
|
2242
2282
|
</li></ul></dd>
|
|
2243
2283
|
|
|
2244
2284
|
|
|
@@ -2714,7 +2754,47 @@ await test()
|
|
|
2714
2754
|
</td>
|
|
2715
2755
|
|
|
2716
2756
|
|
|
2717
|
-
<td class="description last"><p>輸入狀態持久化物件{get:()=>state,set:(state)=>{}},state內含cursors(逐群組游標),省略代表用行程內記憶體(跨呼叫有效,重啟歸零)。假定單行程序列調用,並行請自行加鎖</p></td>
|
|
2757
|
+
<td class="description last"><p>輸入狀態持久化物件{get:()=>state,set:(state)=>{}},state內含cursors(逐群組游標)與cooling(供應商冷卻時間戳,僅cooldownMs>0時使用),省略代表用行程內記憶體(跨呼叫有效,重啟歸零)。假定單行程序列調用,並行請自行加鎖</p></td>
|
|
2758
|
+
</tr>
|
|
2759
|
+
|
|
2760
|
+
|
|
2761
|
+
|
|
2762
|
+
<tr>
|
|
2763
|
+
|
|
2764
|
+
<td class="name"><code>cooldownMs</code></td>
|
|
2765
|
+
|
|
2766
|
+
|
|
2767
|
+
<td class="type">
|
|
2768
|
+
|
|
2769
|
+
|
|
2770
|
+
<span class="param-type">Number</span>
|
|
2771
|
+
|
|
2772
|
+
|
|
2773
|
+
|
|
2774
|
+
|
|
2775
|
+
</td>
|
|
2776
|
+
|
|
2777
|
+
|
|
2778
|
+
<td class="attributes">
|
|
2779
|
+
|
|
2780
|
+
<optional><br>
|
|
2781
|
+
|
|
2782
|
+
|
|
2783
|
+
|
|
2784
|
+
|
|
2785
|
+
|
|
2786
|
+
</td>
|
|
2787
|
+
|
|
2788
|
+
|
|
2789
|
+
|
|
2790
|
+
<td class="default">
|
|
2791
|
+
|
|
2792
|
+
<code>0</code>
|
|
2793
|
+
|
|
2794
|
+
</td>
|
|
2795
|
+
|
|
2796
|
+
|
|
2797
|
+
<td class="description last"><p>輸入供應商冷卻視窗毫秒非負整數,>0啟用:條目(限有明給id者)遭遇限流(HTTP 429,僅api類可偵測)或逾時(TIMEOUT開頭)後,於冷卻視窗內之後續呼叫中被移至鏈尾——只降序不移除,前面全敗時仍會被嘗試,任一次成功立即解除;注意啟用時「providers順序即優先序」會被暫時重排,此即本機制之目的;預設0代表不啟用</p></td>
|
|
2718
2798
|
</tr>
|
|
2719
2799
|
|
|
2720
2800
|
|
|
@@ -7190,7 +7270,7 @@ console.log(getErrorResult(null).error)
|
|
|
7190
7270
|
|
|
7191
7271
|
<dt class="tag-source">Source:</dt>
|
|
7192
7272
|
<dd class="tag-source"><ul class="dummy"><li>
|
|
7193
|
-
<a href="dispatchAiFallback.mjs.html">dispatchAiFallback.mjs</a>, <a href="dispatchAiFallback.mjs.html#
|
|
7273
|
+
<a href="dispatchAiFallback.mjs.html">dispatchAiFallback.mjs</a>, <a href="dispatchAiFallback.mjs.html#line94">line 94</a>
|
|
7194
7274
|
</li></ul></dd>
|
|
7195
7275
|
|
|
7196
7276
|
|
|
@@ -7978,7 +8058,7 @@ await test()
|
|
|
7978
8058
|
</td>
|
|
7979
8059
|
|
|
7980
8060
|
|
|
7981
|
-
<td class="description last"><p>輸入前段名額規格陣列,各元素{ use, fallback, maxRetries?, timeoutMs? }等(
|
|
8061
|
+
<td class="description last"><p>輸入前段名額規格陣列,各元素{ use, fallback, check?, maxRetries?, timeoutMs? }等(check可覆寫頂層檢核;除use/fallback/check外之鍵覆寫該名額呼叫設定)</p></td>
|
|
7982
8062
|
</tr>
|
|
7983
8063
|
|
|
7984
8064
|
|
|
@@ -8014,7 +8094,7 @@ await test()
|
|
|
8014
8094
|
</td>
|
|
8015
8095
|
|
|
8016
8096
|
|
|
8017
|
-
<td class="description last"><p>輸入整合名額規格物件{ use, fallback, prompt?, ... },prompt可為(candidates)=>String
|
|
8097
|
+
<td class="description last"><p>輸入整合名額規格物件{ use, fallback, prompt?, check?, ... },prompt可為(candidates)=>String自訂整合提示詞(省略用預設模板);check為終稿專屬檢核(終稿判準常與候選不同,如須含固定段落),未給則沿用頂層check</p></td>
|
|
8018
8098
|
</tr>
|
|
8019
8099
|
|
|
8020
8100
|
|
|
@@ -8054,7 +8134,7 @@ await test()
|
|
|
8054
8134
|
</td>
|
|
8055
8135
|
|
|
8056
8136
|
|
|
8057
|
-
<td class="description last"><p
|
|
8137
|
+
<td class="description last"><p>輸入檢核函數(json)=>Boolean,作為候選與終稿之共用預設,名額規格與integrate可各自帶check覆寫,預設null</p></td>
|
|
8058
8138
|
</tr>
|
|
8059
8139
|
|
|
8060
8140
|
|
|
@@ -8639,7 +8719,7 @@ await test()
|
|
|
8639
8719
|
</td>
|
|
8640
8720
|
|
|
8641
8721
|
|
|
8642
|
-
<td class="description last"><p
|
|
8722
|
+
<td class="description last"><p>輸入前段共用檢核函數(前段名額規格與integrate可各自帶check覆寫,同runFanout),後段各階段自帶check,預設null</p></td>
|
|
8643
8723
|
</tr>
|
|
8644
8724
|
|
|
8645
8725
|
|
|
@@ -9230,7 +9310,7 @@ await test()
|
|
|
9230
9310
|
<br class="clear">
|
|
9231
9311
|
|
|
9232
9312
|
<footer>
|
|
9233
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026
|
|
9313
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026 15:11:06 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
9234
9314
|
</footer>
|
|
9235
9315
|
|
|
9236
9316
|
<script>prettyPrint();</script>
|
package/docs/index.html
CHANGED
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
<br class="clear">
|
|
72
72
|
|
|
73
73
|
<footer>
|
|
74
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026
|
|
74
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026 15:11:06 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
75
75
|
</footer>
|
|
76
76
|
|
|
77
77
|
<script>prettyPrint();</script>
|
|
@@ -176,7 +176,7 @@ export default resolveProviders
|
|
|
176
176
|
<br class="clear">
|
|
177
177
|
|
|
178
178
|
<footer>
|
|
179
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026
|
|
179
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026 15:11:06 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
180
180
|
</footer>
|
|
181
181
|
|
|
182
182
|
<script>prettyPrint();</script>
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
<section>
|
|
47
47
|
<article>
|
|
48
48
|
<pre class="prettyprint source linenums"><code>import get from 'lodash-es/get.js'
|
|
49
|
+
import omit from 'lodash-es/omit.js'
|
|
49
50
|
import isearr from 'wsemi/src/isearr.mjs'
|
|
50
51
|
import isestr from 'wsemi/src/isestr.mjs'
|
|
51
52
|
import isfun from 'wsemi/src/isfun.mjs'
|
|
@@ -81,6 +82,13 @@ import extractJsonLoose from './extractJsonLoose.mjs'
|
|
|
81
82
|
// 防副作用(建檔/改檔/刪檔/改動系統狀態)之本旨不變。
|
|
82
83
|
|
|
83
84
|
|
|
85
|
+
//本層自用之設定鍵, 其餘鍵(timeoutMs/budgetMs/minAttemptMs/maxRetries/cwd/store/onEvent/
|
|
86
|
+
//retryDelayMs/maxBuffer等)一律原樣轉傳dispatchAiFallback——與各轉接器「剔除自用鍵後
|
|
87
|
+
//原樣轉傳」同一約定; 曾因白名單式轉送漏掉minAttemptMs, 令README教學之工作流層
|
|
88
|
+
//budget保護靜默失效(2026-08-14使用端實測回報), 故改採omit式轉傳杜絕同類漏鍵
|
|
89
|
+
let OWN_KEYS = ['providers', 'spec', 'check', 'parse', 'rawText', 'promptPrefix']
|
|
90
|
+
|
|
91
|
+
|
|
84
92
|
//預設防寫檔前綴(禁副作用, 但豁免唯讀查閱——codex以shell讀檔, 一律禁指令等同禁讀檔)
|
|
85
93
|
let NO_SIDE_EFFECT = [
|
|
86
94
|
'【執行約束】你只需把結果輸出在回覆內容中。',
|
|
@@ -146,10 +154,11 @@ function buildChain(providers, spec) {
|
|
|
146
154
|
* @param {String} [opt.promptPrefix=防寫檔約束] 輸入prompt前綴字串,預設為防寫檔約束,傳''關閉
|
|
147
155
|
* @param {Number} [opt.timeoutMs=300000] 輸入單次嘗試逾時毫秒正整數,全套件統一預設300000
|
|
148
156
|
* @param {Number} [opt.budgetMs=null] 輸入整條遞補鏈之時間預算毫秒正整數,預設null代表不限
|
|
157
|
+
* @param {Number} [opt.minAttemptMs=20000] 輸入搭配budgetMs之開工門檻毫秒正整數,剩餘預算低於此值即不再開工,預設20000
|
|
149
158
|
* @param {Number} [opt.maxRetries=0] 輸入同家重試次數非負整數,預設0(韌性交給遞補;端點不穩偶發空回之模型可調高令同鍵重試)
|
|
150
159
|
* @param {String} [opt.cwd=process.cwd()] 輸入子進程工作目錄字串,預設process.cwd()
|
|
151
160
|
* @param {Object} [opt.store=null] 輸入游標持久化物件{get,set},預設null代表用行程內記憶體
|
|
152
|
-
* @param {Function} [opt.onEvent=null] 輸入遞補層事件回調函數,預設null
|
|
161
|
+
* @param {Function} [opt.onEvent=null] 輸入遞補層事件回調函數,預設null。除上列外之其餘鍵(retryDelayMs、maxBuffer、onStdout等)亦一律原樣轉傳dispatchAiFallback
|
|
153
162
|
* @returns {Promise} 回傳Promise,resolve回傳結果物件,內含ok(是否取得可用結果布林值)、json(解析後物件,rawText模式下為文字)、providerId(實際使用之名稱)、keyIndex、keyId、ms(總耗時毫秒)、tried(遞補嘗試歷程陣列)、error(錯誤訊息字串),本函數不會reject
|
|
154
163
|
* @example
|
|
155
164
|
* //need cli in system PATH
|
|
@@ -232,15 +241,12 @@ async function callAiWithFallback(prompt, opt = {}) {
|
|
|
232
241
|
return check ? check(j) === true : true
|
|
233
242
|
}
|
|
234
243
|
|
|
244
|
+
//剔除本層自用鍵後原樣轉傳(含minAttemptMs/retryDelayMs/maxBuffer等), providers與validate由本層給定
|
|
235
245
|
let r = await dispatchAiFallback(promptPrefix + prompt, {
|
|
246
|
+
...omit(opt, OWN_KEYS),
|
|
236
247
|
providers: chain,
|
|
237
248
|
validate,
|
|
238
249
|
timeoutMs: get(opt, 'timeoutMs', null) || dfTimeoutMs, //全套件統一預設300000
|
|
239
|
-
budgetMs: get(opt, 'budgetMs', null) || undefined,
|
|
240
|
-
maxRetries: get(opt, 'maxRetries', null) || 0,
|
|
241
|
-
cwd: get(opt, 'cwd', null) || process.cwd(),
|
|
242
|
-
store: get(opt, 'store', null) || undefined,
|
|
243
|
-
onEvent: get(opt, 'onEvent', null) || undefined,
|
|
244
250
|
})
|
|
245
251
|
|
|
246
252
|
//result, 已過validate故此處parse必然成功(同一解析器), 重解析僅為取出物件
|
|
@@ -279,7 +285,7 @@ export { buildChain, NO_SIDE_EFFECT }
|
|
|
279
285
|
<br class="clear">
|
|
280
286
|
|
|
281
287
|
<footer>
|
|
282
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026
|
|
288
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026 15:11:06 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
283
289
|
</footer>
|
|
284
290
|
|
|
285
291
|
<script>prettyPrint();</script>
|
|
@@ -167,7 +167,7 @@ export default extractJsonLoose
|
|
|
167
167
|
<br class="clear">
|
|
168
168
|
|
|
169
169
|
<footer>
|
|
170
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026
|
|
170
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026 15:11:06 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
171
171
|
</footer>
|
|
172
172
|
|
|
173
173
|
<script>prettyPrint();</script>
|
|
@@ -97,9 +97,9 @@ ${candidates.map((c, i) => `【候選 ${i + 1}】\n${JSON.stringify(c)}`).join('
|
|
|
97
97
|
* @param {Object} [opt={}] 輸入設定物件,預設{}
|
|
98
98
|
* @param {Object} opt.providers 輸入provider定義表物件(名稱 → 條目),透傳callAiWithFallback
|
|
99
99
|
* @param {String} opt.task 輸入前段各名額共用之任務提示詞字串
|
|
100
|
-
* @param {Array} opt.agents 輸入前段名額規格陣列,各元素{ use, fallback, maxRetries?, timeoutMs? }等(
|
|
101
|
-
* @param {Object} opt.integrate 輸入整合名額規格物件{ use, fallback, prompt?, ... },prompt可為(candidates)=>String
|
|
102
|
-
* @param {Function} [opt.check=null]
|
|
100
|
+
* @param {Array} opt.agents 輸入前段名額規格陣列,各元素{ use, fallback, check?, maxRetries?, timeoutMs? }等(check可覆寫頂層檢核;除use/fallback/check外之鍵覆寫該名額呼叫設定)
|
|
101
|
+
* @param {Object} opt.integrate 輸入整合名額規格物件{ use, fallback, prompt?, check?, ... },prompt可為(candidates)=>String自訂整合提示詞(省略用預設模板);check為終稿專屬檢核(終稿判準常與候選不同,如須含固定段落),未給則沿用頂層check
|
|
102
|
+
* @param {Function} [opt.check=null] 輸入檢核函數(json)=>Boolean,作為候選與終稿之共用預設,名額規格與integrate可各自帶check覆寫,預設null
|
|
103
103
|
* @param {String} [opt.schema=''] 輸入輸出格式示意字串,供預設整合模板嵌入,預設''
|
|
104
104
|
* @param {Number} [opt.minCandidates=2] 輸入進入整合所需之最少成功候選數正整數,未達門檻以首位候選為成果,預設2
|
|
105
105
|
* @param {Object} [opt.callOpt={}] 輸入透傳callAiWithFallback之共用設定(cwd、store、onEvent、timeoutMs、promptPrefix等),預設{}
|
|
@@ -161,9 +161,11 @@ async function runFanout(opt = {}) {
|
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
//前段: 並行多開, 個別失敗不炸整輪
|
|
164
|
+
//各名額可自帶check覆寫頂層(候選與終稿判準本可不同); 自spec抽出而非留在overrides,
|
|
165
|
+
//否則會被後方明給之check靜默覆蓋(曾為死鍵)
|
|
164
166
|
let rsAgents = await Promise.all(agents.map((spec) => {
|
|
165
|
-
let { use, fallback, ...overrides } = spec
|
|
166
|
-
return callAiWithFallback(task, { ...callOpt, ...overrides, providers, spec: { use, fallback }, check })
|
|
167
|
+
let { use, fallback, check: checkAgent, ...overrides } = spec
|
|
168
|
+
return callAiWithFallback(task, { ...callOpt, ...overrides, providers, spec: { use, fallback }, check: isfun(checkAgent) ? checkAgent : check })
|
|
167
169
|
}))
|
|
168
170
|
let candidates = rsAgents.filter((r) => r.ok).map((r) => r.json)
|
|
169
171
|
|
|
@@ -181,9 +183,10 @@ async function runFanout(opt = {}) {
|
|
|
181
183
|
if (!integrate || !isestr(get(integrate, 'use', ''))) {
|
|
182
184
|
return { ok: false, result: null, integrated: false, agents: rsAgents, candidates, totalMs: Date.now() - t0, error: 'integrate spec (with use) is required' }
|
|
183
185
|
}
|
|
184
|
-
|
|
186
|
+
//整合可帶獨立check(終稿判準常較候選嚴, 如須含固定小標題), 未給則沿用頂層check
|
|
187
|
+
let { use, fallback, prompt: intPromptFn, check: checkInt, ...intOverrides } = integrate
|
|
185
188
|
let intPrompt = isfun(intPromptFn) ? intPromptFn(candidates) : defaultIntegratePrompt(candidates, opt)
|
|
186
|
-
let rInt = await callAiWithFallback(intPrompt, { ...callOpt, ...intOverrides, providers, spec: { use, fallback }, check })
|
|
189
|
+
let rInt = await callAiWithFallback(intPrompt, { ...callOpt, ...intOverrides, providers, spec: { use, fallback }, check: isfun(checkInt) ? checkInt : check })
|
|
187
190
|
|
|
188
191
|
return {
|
|
189
192
|
ok: rInt.ok,
|
|
@@ -214,7 +217,7 @@ export { defaultIntegratePrompt }
|
|
|
214
217
|
<br class="clear">
|
|
215
218
|
|
|
216
219
|
<footer>
|
|
217
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026
|
|
220
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026 15:11:06 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
218
221
|
</footer>
|
|
219
222
|
|
|
220
223
|
<script>prettyPrint();</script>
|
|
@@ -76,7 +76,7 @@ import runRolePipeline from './runRolePipeline.mjs'
|
|
|
76
76
|
* @param {Array} opt.agents 輸入前段名額規格陣列(同runFanout)
|
|
77
77
|
* @param {Object} opt.integrate 輸入前段整合名額規格物件(同runFanout)
|
|
78
78
|
* @param {Array} opt.stages 輸入後段階段規格陣列(同runRolePipeline),各階段以ctx.input取得前段成果
|
|
79
|
-
* @param {Function} [opt.check=null]
|
|
79
|
+
* @param {Function} [opt.check=null] 輸入前段共用檢核函數(前段名額規格與integrate可各自帶check覆寫,同runFanout),後段各階段自帶check,預設null
|
|
80
80
|
* @param {String} [opt.schema=''] 輸入輸出格式示意字串(供前段預設整合模板),預設''
|
|
81
81
|
* @param {Number} [opt.minCandidates=2] 輸入前段整合門檻正整數,預設2
|
|
82
82
|
* @param {Object} [opt.callOpt={}] 輸入透傳兩段之共用呼叫設定,預設{}
|
|
@@ -165,7 +165,7 @@ export default runFanoutPipeline
|
|
|
165
165
|
<br class="clear">
|
|
166
166
|
|
|
167
167
|
<footer>
|
|
168
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026
|
|
168
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026 15:11:06 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
169
169
|
</footer>
|
|
170
170
|
|
|
171
171
|
<script>prettyPrint();</script>
|
|
@@ -182,7 +182,7 @@ export default runRolePipeline
|
|
|
182
182
|
<br class="clear">
|
|
183
183
|
|
|
184
184
|
<footer>
|
|
185
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026
|
|
185
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026 15:11:06 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
186
186
|
</footer>
|
|
187
187
|
|
|
188
188
|
<script>prettyPrint();</script>
|
package/package.json
CHANGED
|
@@ -27,6 +27,15 @@ import dfTimeoutMs from './dfTimeoutMs.mjs'
|
|
|
27
27
|
// 【跨次記憶只有游標】成功後游標推進至下一把, 令額度在同組多把金鑰間自動均攤;
|
|
28
28
|
// 死金鑰的代價也被游標攤平——這輪從key1敗轉key2成功後游標停在key3, 下輪不會先碰key1。
|
|
29
29
|
//
|
|
30
|
+
// 【供應商冷卻(選用, cooldownMs>0啟用, 預設關閉)】多階段工作流的每一階段都會從鏈首
|
|
31
|
+
// 重新探測同一家已失效的供應商——限流時每階段各踩一輪429、卡死時各燒一次完整逾時
|
|
32
|
+
// (使用端實測: 一次107秒的多階段請求中72秒耗在重複踩同一組429, 啟用冷卻後降至15秒)。
|
|
33
|
+
// 設計與「金鑰停用清單」(已否決)的關鍵差異: 以「條目」為單位、短視窗、且「只降序不移除」
|
|
34
|
+
// ——冷卻中的條目移到鏈尾而非移除, 前面全敗時照樣會被嘗試, 故不存在把已恢復服務冰住的問題;
|
|
35
|
+
// 任一次成功立即解除。觸發限於限流(HTTP 429, 僅api-openai-compat可靠偵測; CLI類之限流
|
|
36
|
+
// 埋在stderr文字中不納入)與逾時(TIMEOUT開頭, 各kind皆可)兩類——其餘失敗已有換金鑰換家
|
|
37
|
+
// 機制處理, 納入反而誤傷。狀態存於state.cooling, 與cursors同走store持久化。
|
|
38
|
+
//
|
|
30
39
|
// 【時間預算】budgetMs限制整輪遞補的總時長, 剩餘預算會壓進每次呼叫的timeoutMs,
|
|
31
40
|
// 防止多家連續卡逾時而撞破外部排程的執行上限。
|
|
32
41
|
//
|
|
@@ -60,7 +69,7 @@ import dfTimeoutMs from './dfTimeoutMs.mjs'
|
|
|
60
69
|
|
|
61
70
|
|
|
62
71
|
//fallback層自用之設定鍵, 其餘鍵作為各attempt之共用預設原樣轉傳
|
|
63
|
-
let FALLBACK_KEYS = ['providers', 'budgetMs', 'minAttemptMs', 'store', 'onEvent']
|
|
72
|
+
let FALLBACK_KEYS = ['providers', 'budgetMs', 'minAttemptMs', 'cooldownMs', 'store', 'onEvent']
|
|
64
73
|
|
|
65
74
|
|
|
66
75
|
//providers條目自用之設定鍵, 其餘鍵(含kind)即該條目之opt原樣轉傳對應轉接器
|
|
@@ -139,7 +148,8 @@ function isKeyIndependentFail(r) {
|
|
|
139
148
|
* @param {Array} [opt.providers[].keys=[]] 輸入同一服務之多把API key字串陣列,逐次注入輪替(kind為opencode時須同時於條目給予provider),省略代表沿用CLI既有登入狀態之單一虛擬金鑰
|
|
140
149
|
* @param {Number} [opt.budgetMs=null] 輸入整輪遞補之時間上限毫秒正整數,剩餘預算會壓進每次呼叫之timeoutMs,預設null代表不限
|
|
141
150
|
* @param {Number} [opt.minAttemptMs=20000] 輸入單次嘗試之最低剩餘預算毫秒正整數,剩餘低於此值即停止嘗試回報budget exhausted,預設20000
|
|
142
|
-
* @param {Object} [opt.store=null] 輸入狀態持久化物件{get:()=>state,set:(state)=>{}},state內含cursors(逐群組游標),省略代表用行程內記憶體(跨呼叫有效,重啟歸零)。假定單行程序列調用,並行請自行加鎖
|
|
151
|
+
* @param {Object} [opt.store=null] 輸入狀態持久化物件{get:()=>state,set:(state)=>{}},state內含cursors(逐群組游標)與cooling(供應商冷卻時間戳,僅cooldownMs>0時使用),省略代表用行程內記憶體(跨呼叫有效,重啟歸零)。假定單行程序列調用,並行請自行加鎖
|
|
152
|
+
* @param {Number} [opt.cooldownMs=0] 輸入供應商冷卻視窗毫秒非負整數,>0啟用:條目(限有明給id者)遭遇限流(HTTP 429,僅api類可偵測)或逾時(TIMEOUT開頭)後,於冷卻視窗內之後續呼叫中被移至鏈尾——只降序不移除,前面全敗時仍會被嘗試,任一次成功立即解除;注意啟用時「providers順序即優先序」會被暫時重排,此即本機制之目的;預設0代表不啟用
|
|
143
153
|
* @param {Function} [opt.onEvent=null] 輸入事件回調函數(ev)=>{},ev.type可為'try'、'ok'、'next-key'、'skip-group'、'budget-out';失敗事件(next-key/skip-group)另帶stdout(被拒回覆)與stderr(錯誤輸出)供診斷,兩者於失敗路徑已由轉接器截斷;回調拋出例外不影響主流程,預設null
|
|
144
154
|
* @param {Number} [opt.timeoutMs=300000] 輸入各attempt共用之逾時毫秒正整數,條目可覆寫,全套件統一預設300000
|
|
145
155
|
* @param {String|Function} [opt.validate=undefined] 輸入各attempt共用之stdout驗證規則,條目可覆寫,預設undefined
|
|
@@ -235,6 +245,9 @@ async function dispatchAiFallback(prompt, opt = {}) {
|
|
|
235
245
|
if (!isobj(state.cursors)) {
|
|
236
246
|
state.cursors = {}
|
|
237
247
|
}
|
|
248
|
+
if (!isobj(state.cooling)) {
|
|
249
|
+
state.cooling = {}
|
|
250
|
+
}
|
|
238
251
|
let saveState = () => {
|
|
239
252
|
if (useStore) {
|
|
240
253
|
try {
|
|
@@ -244,6 +257,43 @@ async function dispatchAiFallback(prompt, opt = {}) {
|
|
|
244
257
|
}
|
|
245
258
|
}
|
|
246
259
|
|
|
260
|
+
//cooldownMs, 無效視為0=不啟用(現行行為零改變)
|
|
261
|
+
let cooldownMs = get(opt, 'cooldownMs', null)
|
|
262
|
+
if (!ispint(cooldownMs)) {
|
|
263
|
+
cooldownMs = 0
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
cooldownMs = cint(cooldownMs)
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
//供應商冷卻: 冷卻中的條目「只降序不移除」——移到鏈尾, 前面全敗時仍會被嘗試,
|
|
270
|
+
//故不存在把已恢復服務冰住的問題(此為與「金鑰停用清單」的關鍵差異, 後者已被否決)。
|
|
271
|
+
//僅追蹤有明給id之條目(索引式id會因重排而錯位); 過期項順手清除
|
|
272
|
+
if (cooldownMs > 0) {
|
|
273
|
+
let now = Date.now()
|
|
274
|
+
let act = []
|
|
275
|
+
let cool = []
|
|
276
|
+
let dirty = false
|
|
277
|
+
for (let p of providers) {
|
|
278
|
+
let pid = get(p, 'id', null)
|
|
279
|
+
let ts = isestr(pid) ? get(state.cooling, pid, null) : null
|
|
280
|
+
if (ispint(ts) && (now - ts) < cooldownMs) {
|
|
281
|
+
cool.push(p)
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
if (isestr(pid) && state.cooling[pid] !== undefined) {
|
|
285
|
+
delete state.cooling[pid] //冷卻已過期, 清除
|
|
286
|
+
dirty = true
|
|
287
|
+
}
|
|
288
|
+
act.push(p)
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
providers = [...act, ...cool]
|
|
292
|
+
if (dirty) {
|
|
293
|
+
saveState()
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
247
297
|
//onEvent, 回調拋出例外不得中斷主流程
|
|
248
298
|
let onEvent = get(opt, 'onEvent', null)
|
|
249
299
|
let emit = (ev) => {
|
|
@@ -266,9 +316,10 @@ async function dispatchAiFallback(prompt, opt = {}) {
|
|
|
266
316
|
for (let ig = 0; ig < providers.length; ig++) {
|
|
267
317
|
let entry = providers[ig]
|
|
268
318
|
|
|
269
|
-
//id,
|
|
319
|
+
//id, 無效回退條目索引字串; idExplicit供冷卻機制判別(索引式id不參與冷卻)
|
|
270
320
|
let id = get(entry, 'id', null)
|
|
271
|
-
|
|
321
|
+
let idExplicit = isestr(id)
|
|
322
|
+
if (!idExplicit) {
|
|
272
323
|
id = String(ig)
|
|
273
324
|
}
|
|
274
325
|
|
|
@@ -331,8 +382,12 @@ async function dispatchAiFallback(prompt, opt = {}) {
|
|
|
331
382
|
emit({ type: 'try', providerId: id, keyIndex, keyId, kind, model })
|
|
332
383
|
let r = await dispatchAi(kind, prompt, attemptOpt)
|
|
333
384
|
|
|
334
|
-
//成功, 推進游標(額度均攤)
|
|
385
|
+
//成功, 推進游標(額度均攤)並回傳; 任一次成功立即解除該家冷卻
|
|
335
386
|
if (r.ok) {
|
|
387
|
+
if (cooldownMs > 0 && idExplicit && state.cooling[id] !== undefined) {
|
|
388
|
+
delete state.cooling[id]
|
|
389
|
+
saveState()
|
|
390
|
+
}
|
|
336
391
|
if (nk > 0) {
|
|
337
392
|
state.cursors[id] = (keyIndex + 1) % nk
|
|
338
393
|
saveState()
|
|
@@ -345,6 +400,16 @@ async function dispatchAiFallback(prompt, opt = {}) {
|
|
|
345
400
|
//失敗分流
|
|
346
401
|
lastResult = r
|
|
347
402
|
lastMeta = { providerId: id, keyIndex, kind, model }
|
|
403
|
+
//冷卻觸發: 限流(HTTP 429, 僅api類可偵測)與逾時(TIMEOUT開頭, CLI與api皆可)兩類——
|
|
404
|
+
//其餘失敗(金鑰無效/服務端錯誤)已有換金鑰換家機制處理, 納入冷卻反而誤傷
|
|
405
|
+
if (cooldownMs > 0 && idExplicit) {
|
|
406
|
+
let isCoolTrigger = (r.code === 429) || (isestr(r.error) && r.error.indexOf('TIMEOUT') === 0)
|
|
407
|
+
if (isCoolTrigger) {
|
|
408
|
+
state.cooling[id] = Date.now()
|
|
409
|
+
saveState()
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
|
|
348
413
|
//失敗事件與tried一併帶被拒回覆(stdout)與錯誤輸出(stderr), 供呼叫端診斷失敗原因
|
|
349
414
|
//(如驗證失敗時模型究竟回了什麼); 兩者於失敗路徑已由轉接器截斷(≤500/1000字元), 不會過大
|
|
350
415
|
if (isKeyIndependentFail(r)) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import get from 'lodash-es/get.js'
|
|
2
|
+
import omit from 'lodash-es/omit.js'
|
|
2
3
|
import isearr from 'wsemi/src/isearr.mjs'
|
|
3
4
|
import isestr from 'wsemi/src/isestr.mjs'
|
|
4
5
|
import isfun from 'wsemi/src/isfun.mjs'
|
|
@@ -34,6 +35,13 @@ import extractJsonLoose from './extractJsonLoose.mjs'
|
|
|
34
35
|
// 防副作用(建檔/改檔/刪檔/改動系統狀態)之本旨不變。
|
|
35
36
|
|
|
36
37
|
|
|
38
|
+
//本層自用之設定鍵, 其餘鍵(timeoutMs/budgetMs/minAttemptMs/maxRetries/cwd/store/onEvent/
|
|
39
|
+
//retryDelayMs/maxBuffer等)一律原樣轉傳dispatchAiFallback——與各轉接器「剔除自用鍵後
|
|
40
|
+
//原樣轉傳」同一約定; 曾因白名單式轉送漏掉minAttemptMs, 令README教學之工作流層
|
|
41
|
+
//budget保護靜默失效(2026-08-14使用端實測回報), 故改採omit式轉傳杜絕同類漏鍵
|
|
42
|
+
let OWN_KEYS = ['providers', 'spec', 'check', 'parse', 'rawText', 'promptPrefix']
|
|
43
|
+
|
|
44
|
+
|
|
37
45
|
//預設防寫檔前綴(禁副作用, 但豁免唯讀查閱——codex以shell讀檔, 一律禁指令等同禁讀檔)
|
|
38
46
|
let NO_SIDE_EFFECT = [
|
|
39
47
|
'【執行約束】你只需把結果輸出在回覆內容中。',
|
|
@@ -99,10 +107,11 @@ function buildChain(providers, spec) {
|
|
|
99
107
|
* @param {String} [opt.promptPrefix=防寫檔約束] 輸入prompt前綴字串,預設為防寫檔約束,傳''關閉
|
|
100
108
|
* @param {Number} [opt.timeoutMs=300000] 輸入單次嘗試逾時毫秒正整數,全套件統一預設300000
|
|
101
109
|
* @param {Number} [opt.budgetMs=null] 輸入整條遞補鏈之時間預算毫秒正整數,預設null代表不限
|
|
110
|
+
* @param {Number} [opt.minAttemptMs=20000] 輸入搭配budgetMs之開工門檻毫秒正整數,剩餘預算低於此值即不再開工,預設20000
|
|
102
111
|
* @param {Number} [opt.maxRetries=0] 輸入同家重試次數非負整數,預設0(韌性交給遞補;端點不穩偶發空回之模型可調高令同鍵重試)
|
|
103
112
|
* @param {String} [opt.cwd=process.cwd()] 輸入子進程工作目錄字串,預設process.cwd()
|
|
104
113
|
* @param {Object} [opt.store=null] 輸入游標持久化物件{get,set},預設null代表用行程內記憶體
|
|
105
|
-
* @param {Function} [opt.onEvent=null] 輸入遞補層事件回調函數,預設null
|
|
114
|
+
* @param {Function} [opt.onEvent=null] 輸入遞補層事件回調函數,預設null。除上列外之其餘鍵(retryDelayMs、maxBuffer、onStdout等)亦一律原樣轉傳dispatchAiFallback
|
|
106
115
|
* @returns {Promise} 回傳Promise,resolve回傳結果物件,內含ok(是否取得可用結果布林值)、json(解析後物件,rawText模式下為文字)、providerId(實際使用之名稱)、keyIndex、keyId、ms(總耗時毫秒)、tried(遞補嘗試歷程陣列)、error(錯誤訊息字串),本函數不會reject
|
|
107
116
|
* @example
|
|
108
117
|
* //need cli in system PATH
|
|
@@ -185,15 +194,12 @@ async function callAiWithFallback(prompt, opt = {}) {
|
|
|
185
194
|
return check ? check(j) === true : true
|
|
186
195
|
}
|
|
187
196
|
|
|
197
|
+
//剔除本層自用鍵後原樣轉傳(含minAttemptMs/retryDelayMs/maxBuffer等), providers與validate由本層給定
|
|
188
198
|
let r = await dispatchAiFallback(promptPrefix + prompt, {
|
|
199
|
+
...omit(opt, OWN_KEYS),
|
|
189
200
|
providers: chain,
|
|
190
201
|
validate,
|
|
191
202
|
timeoutMs: get(opt, 'timeoutMs', null) || dfTimeoutMs, //全套件統一預設300000
|
|
192
|
-
budgetMs: get(opt, 'budgetMs', null) || undefined,
|
|
193
|
-
maxRetries: get(opt, 'maxRetries', null) || 0,
|
|
194
|
-
cwd: get(opt, 'cwd', null) || process.cwd(),
|
|
195
|
-
store: get(opt, 'store', null) || undefined,
|
|
196
|
-
onEvent: get(opt, 'onEvent', null) || undefined,
|
|
197
203
|
})
|
|
198
204
|
|
|
199
205
|
//result, 已過validate故此處parse必然成功(同一解析器), 重解析僅為取出物件
|