w-dispatch-ai 1.0.4 → 1.0.6
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 +94 -17
- package/dist/w-dispatch-ai.umd.js +2 -2
- package/dist/w-dispatch-ai.umd.js.map +1 -1
- package/docs/WDispatchAi.mjs.html +8 -4
- package/docs/adapters.mjs.html +2 -2
- package/docs/dfTimeoutMs.mjs.html +98 -0
- package/docs/dispatchAi.mjs.html +2 -2
- package/docs/dispatchAiFallback.mjs.html +16 -11
- package/docs/dispatchAiWkf.mjs.html +11 -2
- package/docs/dispatchAntigravity.mjs.html +23 -12
- package/docs/dispatchApiOpenaiCompat.mjs.html +5 -4
- package/docs/dispatchClaude.mjs.html +17 -4
- package/docs/dispatchCodex.mjs.html +16 -3
- package/docs/dispatchOpencode.mjs.html +16 -3
- package/docs/getCliArgs.mjs.html +2 -2
- package/docs/getErrorResult.mjs.html +2 -2
- package/docs/global.html +501 -35
- package/docs/index.html +2 -2
- package/docs/resolveProviders.mjs.html +189 -0
- package/docs/wkf_callAiWithFallback.mjs.html +29 -13
- package/docs/wkf_extractJsonLoose.mjs.html +2 -2
- package/docs/wkf_runFanout.mjs.html +2 -2
- package/docs/wkf_runFanoutPipeline.mjs.html +2 -2
- package/docs/wkf_runRolePipeline.mjs.html +2 -2
- package/g.mjs +7 -7
- package/package.json +1 -1
- package/src/WDispatchAi.mjs +6 -2
- package/src/dfTimeoutMs.mjs +26 -0
- package/src/dispatchAiFallback.mjs +14 -9
- package/src/dispatchAiWkf.mjs +9 -0
- package/src/dispatchAntigravity.mjs +21 -10
- package/src/dispatchApiOpenaiCompat.mjs +3 -2
- package/src/dispatchClaude.mjs +15 -2
- package/src/dispatchCodex.mjs +14 -1
- package/src/dispatchOpencode.mjs +14 -1
- package/src/providers.mjs +133 -0
- package/src/resolveProviders.mjs +117 -0
- package/src/wkf/callAiWithFallback.mjs +27 -11
- package/test/unit-WDispatchAi.test.mjs +9 -3
- package/test/unit-callAiWithFallback.test.mjs +15 -0
- package/test/unit-dispatchAi.test.mjs +1 -1
- package/test/unit-dispatchAiFallback.test.mjs +25 -0
- package/test/unit-dispatchAiWkf.test.mjs +8 -0
- package/test/unit-dispatchAntigravity.test.mjs +25 -5
- package/test/unit-providers.test.mjs +66 -0
- package/test/unit-resolveProviders.test.mjs +85 -0
package/docs/index.html
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
<nav >
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
<h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#WDispatchAi">WDispatchAi</a></li><li><a href="global.html#adapters">adapters</a></li><li><a href="global.html#buildChain">buildChain</a></li><li><a href="global.html#buildValidator">buildValidator</a></li><li><a href="global.html#callAiWithFallback">callAiWithFallback</a></li><li><a href="global.html#callOnce">callOnce</a></li><li><a href="global.html#defaultIntegratePrompt">defaultIntegratePrompt</a></li><li><a href="global.html#dispatchAi">dispatchAi</a></li><li><a href="global.html#dispatchAiFallback">dispatchAiFallback</a></li><li><a href="global.html#dispatchAiWkf">dispatchAiWkf</a></li><li><a href="global.html#dispatchAntigravity">dispatchAntigravity</a></li><li><a href="global.html#dispatchApiOpenaiCompat">dispatchApiOpenaiCompat</a></li><li><a href="global.html#dispatchClaude">dispatchClaude</a></li><li><a href="global.html#dispatchCodex">dispatchCodex</a></li><li><a href="global.html#dispatchOpencode">dispatchOpencode</a></li><li><a href="global.html#extractJsonLoose">extractJsonLoose</a></li><li><a href="global.html#getCliArgs">getCliArgs</a></li><li><a href="global.html#getErrorResult">getErrorResult</a></li><li><a href="global.html#isKeyIndependentFail">isKeyIndependentFail</a></li><li><a href="global.html#runFanout">runFanout</a></li><li><a href="global.html#runFanoutPipeline">runFanoutPipeline</a></li><li><a href="global.html#runRolePipeline">runRolePipeline</a></li></ul>
|
|
32
|
+
<h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#WDispatchAi">WDispatchAi</a></li><li><a href="global.html#adapters">adapters</a></li><li><a href="global.html#buildChain">buildChain</a></li><li><a href="global.html#buildValidator">buildValidator</a></li><li><a href="global.html#callAiWithFallback">callAiWithFallback</a></li><li><a href="global.html#callOnce">callOnce</a></li><li><a href="global.html#defaultIntegratePrompt">defaultIntegratePrompt</a></li><li><a href="global.html#dfTimeoutMs">dfTimeoutMs</a></li><li><a href="global.html#dispatchAi">dispatchAi</a></li><li><a href="global.html#dispatchAiFallback">dispatchAiFallback</a></li><li><a href="global.html#dispatchAiWkf">dispatchAiWkf</a></li><li><a href="global.html#dispatchAntigravity">dispatchAntigravity</a></li><li><a href="global.html#dispatchApiOpenaiCompat">dispatchApiOpenaiCompat</a></li><li><a href="global.html#dispatchClaude">dispatchClaude</a></li><li><a href="global.html#dispatchCodex">dispatchCodex</a></li><li><a href="global.html#dispatchOpencode">dispatchOpencode</a></li><li><a href="global.html#extractJsonLoose">extractJsonLoose</a></li><li><a href="global.html#getCliArgs">getCliArgs</a></li><li><a href="global.html#getErrorResult">getErrorResult</a></li><li><a href="global.html#isKeyIndependentFail">isKeyIndependentFail</a></li><li><a href="global.html#resolveProviders">resolveProviders</a></li><li><a href="global.html#runFanout">runFanout</a></li><li><a href="global.html#runFanoutPipeline">runFanoutPipeline</a></li><li><a href="global.html#runRolePipeline">runRolePipeline</a></li></ul>
|
|
33
33
|
|
|
34
34
|
</nav>
|
|
35
35
|
|
|
@@ -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
|
|
74
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026 12:30:07 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
75
75
|
</footer>
|
|
76
76
|
|
|
77
77
|
<script>prettyPrint();</script>
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
|
|
5
|
+
<meta charset="utf-8">
|
|
6
|
+
<title>resolveProviders.mjs - Documentation</title>
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
<script src="scripts/prettify/prettify.js"></script>
|
|
10
|
+
<script src="scripts/prettify/lang-css.js"></script>
|
|
11
|
+
<!--[if lt IE 9]>
|
|
12
|
+
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
|
13
|
+
<![endif]-->
|
|
14
|
+
<link type="text/css" rel="stylesheet" href="styles/prettify.css">
|
|
15
|
+
<link type="text/css" rel="stylesheet" href="styles/jsdoc.css">
|
|
16
|
+
<script src="scripts/nav.js" defer></script>
|
|
17
|
+
|
|
18
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
19
|
+
</head>
|
|
20
|
+
<body>
|
|
21
|
+
|
|
22
|
+
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
|
|
23
|
+
<label for="nav-trigger" class="navicon-button x">
|
|
24
|
+
<div class="navicon"></div>
|
|
25
|
+
</label>
|
|
26
|
+
|
|
27
|
+
<label for="nav-trigger" class="overlay"></label>
|
|
28
|
+
|
|
29
|
+
<nav >
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
<h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#WDispatchAi">WDispatchAi</a></li><li><a href="global.html#adapters">adapters</a></li><li><a href="global.html#buildChain">buildChain</a></li><li><a href="global.html#buildValidator">buildValidator</a></li><li><a href="global.html#callAiWithFallback">callAiWithFallback</a></li><li><a href="global.html#callOnce">callOnce</a></li><li><a href="global.html#defaultIntegratePrompt">defaultIntegratePrompt</a></li><li><a href="global.html#dfTimeoutMs">dfTimeoutMs</a></li><li><a href="global.html#dispatchAi">dispatchAi</a></li><li><a href="global.html#dispatchAiFallback">dispatchAiFallback</a></li><li><a href="global.html#dispatchAiWkf">dispatchAiWkf</a></li><li><a href="global.html#dispatchAntigravity">dispatchAntigravity</a></li><li><a href="global.html#dispatchApiOpenaiCompat">dispatchApiOpenaiCompat</a></li><li><a href="global.html#dispatchClaude">dispatchClaude</a></li><li><a href="global.html#dispatchCodex">dispatchCodex</a></li><li><a href="global.html#dispatchOpencode">dispatchOpencode</a></li><li><a href="global.html#extractJsonLoose">extractJsonLoose</a></li><li><a href="global.html#getCliArgs">getCliArgs</a></li><li><a href="global.html#getErrorResult">getErrorResult</a></li><li><a href="global.html#isKeyIndependentFail">isKeyIndependentFail</a></li><li><a href="global.html#resolveProviders">resolveProviders</a></li><li><a href="global.html#runFanout">runFanout</a></li><li><a href="global.html#runFanoutPipeline">runFanoutPipeline</a></li><li><a href="global.html#runRolePipeline">runRolePipeline</a></li></ul>
|
|
33
|
+
|
|
34
|
+
</nav>
|
|
35
|
+
|
|
36
|
+
<div id="main">
|
|
37
|
+
|
|
38
|
+
<h1 class="page-title">resolveProviders.mjs</h1>
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
<section>
|
|
47
|
+
<article>
|
|
48
|
+
<pre class="prettyprint source linenums"><code>import get from 'lodash-es/get.js'
|
|
49
|
+
import omit from 'lodash-es/omit.js'
|
|
50
|
+
import isarr from 'wsemi/src/isarr.mjs'
|
|
51
|
+
import isobj from 'wsemi/src/isobj.mjs'
|
|
52
|
+
import isestr from 'wsemi/src/isestr.mjs'
|
|
53
|
+
import isearr from 'wsemi/src/isearr.mjs'
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
// resolveProviders.mjs — 把providers定義檔展開為可直接使用的條目
|
|
57
|
+
//
|
|
58
|
+
// 【為何需要】providers.mjs之條目以envVar間接引用金鑰(機密不落設定檔, 只寫變數名),
|
|
59
|
+
// 而dispatchAiFallback只認keys陣列——本函數負責envVar → keys之展開,
|
|
60
|
+
// 缺對應環境變數者停用該條目並列入skipped回報(不中斷、不throw),
|
|
61
|
+
// 訂閱登入態條目(claude/codex等無envVar)原樣通過。
|
|
62
|
+
//
|
|
63
|
+
// 【自選】opt.pick給id陣列即可只取用部分條目, 且依pick之順序回傳
|
|
64
|
+
// (順序即dispatchAiFallback之優先序); 查無之id列入missing回報。
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* 展開providers定義條目:envVar → keys,並可依id自選子集
|
|
69
|
+
*
|
|
70
|
+
* 特點:
|
|
71
|
+
* 條目之envVar依env來源(預設process.env)展開為keys陣列(變數值以逗號分隔多把),envVar欄位自輸出移除;
|
|
72
|
+
* 缺對應環境變數(或值為空)之條目停用並列入skipped,不中斷不throw;
|
|
73
|
+
* 無envVar之條目(訂閱登入態CLI)原樣通過;條目已自帶有效keys者以keys為準;
|
|
74
|
+
* opt.pick可依id自選子集並以pick順序回傳(順序即遞補優先序);
|
|
75
|
+
* 輸入陣列與條目皆不被改動(輸出為淺拷貝)
|
|
76
|
+
*
|
|
77
|
+
* @param {Array} providers 輸入providers條目物件陣列(如providers.mjs之預設匯出)
|
|
78
|
+
* @param {Object} [opt={}] 輸入設定物件,預設{}
|
|
79
|
+
* @param {Object} [opt.env=process.env] 輸入金鑰來源物件(變數名 → 逗號分隔之金鑰字串),預設process.env
|
|
80
|
+
* @param {Array} [opt.pick=null] 輸入自選id字串陣列,依此順序回傳對應條目,查無之id列入missing,預設null代表全取(依原順序)
|
|
81
|
+
* @returns {Object} 回傳物件,內含providers(可直接餵dispatchAiFallback之條目陣列)、table(id對條目之物件,可直接餵dispatchAiWkf)、skipped(缺環境變數而停用之{id,envVar}陣列)、missing(pick查無之id字串陣列)
|
|
82
|
+
* @example
|
|
83
|
+
*
|
|
84
|
+
* import resolveProviders from './src/resolveProviders.mjs'
|
|
85
|
+
* import providersAll from './src/providers.mjs'
|
|
86
|
+
*
|
|
87
|
+
* process.loadEnvFile('./.env') //金鑰放.env, 變數值以逗號分隔多把
|
|
88
|
+
*
|
|
89
|
+
* //全取: envVar展開為keys, 缺環境變數者列入skipped
|
|
90
|
+
* let { providers, table, skipped } = resolveProviders(providersAll)
|
|
91
|
+
* console.log(providers.length, skipped)
|
|
92
|
+
* // => 10 []
|
|
93
|
+
*
|
|
94
|
+
* //自選: 依pick順序回傳(順序即遞補優先序), 可直接餵dispatchAiFallback
|
|
95
|
+
* let r2 = resolveProviders(providersAll, { pick: ['agnes:agnes-2.5-flash', 'claude:sonnet'] })
|
|
96
|
+
* console.log(r2.providers.map((p) => p.id))
|
|
97
|
+
* // => [ 'agnes:agnes-2.5-flash', 'claude:sonnet' ]
|
|
98
|
+
*
|
|
99
|
+
* //table可直接餵dispatchAiWkf之providers定義表
|
|
100
|
+
* //let wkf = dispatchAiWkf({ providers: r2.table, defaults: { timeoutMs: 1200000 } })
|
|
101
|
+
*
|
|
102
|
+
*/
|
|
103
|
+
function resolveProviders(providers, opt = {}) {
|
|
104
|
+
|
|
105
|
+
//env, 無效回退process.env(瀏覽器環境無process則空物件)
|
|
106
|
+
let env = get(opt, 'env', null)
|
|
107
|
+
if (!isobj(env)) {
|
|
108
|
+
env = (typeof process !== 'undefined' && process && isobj(process.env)) ? process.env : {}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
//providersRaw
|
|
112
|
+
let providersRaw = isarr(providers) ? providers.filter(isobj) : []
|
|
113
|
+
|
|
114
|
+
//pick, 依id自選並依pick順序回傳
|
|
115
|
+
let pick = get(opt, 'pick', null)
|
|
116
|
+
let missing = []
|
|
117
|
+
let selected = providersRaw
|
|
118
|
+
if (isearr(pick)) {
|
|
119
|
+
selected = []
|
|
120
|
+
for (let id of pick) {
|
|
121
|
+
let entry = providersRaw.find((p) => get(p, 'id', null) === id)
|
|
122
|
+
if (entry) {
|
|
123
|
+
selected.push(entry)
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
missing.push(String(id))
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
//展開envVar → keys
|
|
132
|
+
let out = []
|
|
133
|
+
let skipped = []
|
|
134
|
+
for (let entry of selected) {
|
|
135
|
+
let envVar = get(entry, 'envVar', null)
|
|
136
|
+
|
|
137
|
+
//無envVar(訂閱登入態CLI)或已自帶有效keys, 原樣通過(僅移除envVar欄位)
|
|
138
|
+
if (!isestr(envVar) || isearr(get(entry, 'keys', null))) {
|
|
139
|
+
out.push(omit(entry, ['envVar']))
|
|
140
|
+
continue
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
//envVar → keys, 變數值以逗號分隔多把
|
|
144
|
+
let keys = String(get(env, envVar, '') || '').split(',').map((k) => k.trim()).filter(Boolean)
|
|
145
|
+
if (keys.length === 0) {
|
|
146
|
+
|
|
147
|
+
//缺環境變數: 停用該條目並回報, 不中斷(設計providers原則§四.4)
|
|
148
|
+
skipped.push({ id: get(entry, 'id', ''), envVar })
|
|
149
|
+
continue
|
|
150
|
+
}
|
|
151
|
+
out.push({ ...omit(entry, ['envVar']), keys })
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
//table, id → 條目, 可直接作dispatchAiWkf之providers定義表
|
|
155
|
+
let table = {}
|
|
156
|
+
for (let entry of out) {
|
|
157
|
+
table[entry.id] = entry
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return { providers: out, table, skipped, missing }
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
export default resolveProviders
|
|
165
|
+
</code></pre>
|
|
166
|
+
</article>
|
|
167
|
+
</section>
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
</div>
|
|
175
|
+
|
|
176
|
+
<br class="clear">
|
|
177
|
+
|
|
178
|
+
<footer>
|
|
179
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026 12:30:07 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
180
|
+
</footer>
|
|
181
|
+
|
|
182
|
+
<script>prettyPrint();</script>
|
|
183
|
+
<script src="scripts/polyfill.js"></script>
|
|
184
|
+
<script src="scripts/linenumber.js"></script>
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
</body>
|
|
189
|
+
</html>
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
<nav >
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
<h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#WDispatchAi">WDispatchAi</a></li><li><a href="global.html#adapters">adapters</a></li><li><a href="global.html#buildChain">buildChain</a></li><li><a href="global.html#buildValidator">buildValidator</a></li><li><a href="global.html#callAiWithFallback">callAiWithFallback</a></li><li><a href="global.html#callOnce">callOnce</a></li><li><a href="global.html#defaultIntegratePrompt">defaultIntegratePrompt</a></li><li><a href="global.html#dispatchAi">dispatchAi</a></li><li><a href="global.html#dispatchAiFallback">dispatchAiFallback</a></li><li><a href="global.html#dispatchAiWkf">dispatchAiWkf</a></li><li><a href="global.html#dispatchAntigravity">dispatchAntigravity</a></li><li><a href="global.html#dispatchApiOpenaiCompat">dispatchApiOpenaiCompat</a></li><li><a href="global.html#dispatchClaude">dispatchClaude</a></li><li><a href="global.html#dispatchCodex">dispatchCodex</a></li><li><a href="global.html#dispatchOpencode">dispatchOpencode</a></li><li><a href="global.html#extractJsonLoose">extractJsonLoose</a></li><li><a href="global.html#getCliArgs">getCliArgs</a></li><li><a href="global.html#getErrorResult">getErrorResult</a></li><li><a href="global.html#isKeyIndependentFail">isKeyIndependentFail</a></li><li><a href="global.html#runFanout">runFanout</a></li><li><a href="global.html#runFanoutPipeline">runFanoutPipeline</a></li><li><a href="global.html#runRolePipeline">runRolePipeline</a></li></ul>
|
|
32
|
+
<h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#WDispatchAi">WDispatchAi</a></li><li><a href="global.html#adapters">adapters</a></li><li><a href="global.html#buildChain">buildChain</a></li><li><a href="global.html#buildValidator">buildValidator</a></li><li><a href="global.html#callAiWithFallback">callAiWithFallback</a></li><li><a href="global.html#callOnce">callOnce</a></li><li><a href="global.html#defaultIntegratePrompt">defaultIntegratePrompt</a></li><li><a href="global.html#dfTimeoutMs">dfTimeoutMs</a></li><li><a href="global.html#dispatchAi">dispatchAi</a></li><li><a href="global.html#dispatchAiFallback">dispatchAiFallback</a></li><li><a href="global.html#dispatchAiWkf">dispatchAiWkf</a></li><li><a href="global.html#dispatchAntigravity">dispatchAntigravity</a></li><li><a href="global.html#dispatchApiOpenaiCompat">dispatchApiOpenaiCompat</a></li><li><a href="global.html#dispatchClaude">dispatchClaude</a></li><li><a href="global.html#dispatchCodex">dispatchCodex</a></li><li><a href="global.html#dispatchOpencode">dispatchOpencode</a></li><li><a href="global.html#extractJsonLoose">extractJsonLoose</a></li><li><a href="global.html#getCliArgs">getCliArgs</a></li><li><a href="global.html#getErrorResult">getErrorResult</a></li><li><a href="global.html#isKeyIndependentFail">isKeyIndependentFail</a></li><li><a href="global.html#resolveProviders">resolveProviders</a></li><li><a href="global.html#runFanout">runFanout</a></li><li><a href="global.html#runFanoutPipeline">runFanoutPipeline</a></li><li><a href="global.html#runRolePipeline">runRolePipeline</a></li></ul>
|
|
33
33
|
|
|
34
34
|
</nav>
|
|
35
35
|
|
|
@@ -46,11 +46,13 @@
|
|
|
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'
|
|
52
53
|
import isobj from 'wsemi/src/isobj.mjs'
|
|
53
54
|
import dispatchAiFallback from '../dispatchAiFallback.mjs'
|
|
55
|
+
import dfTimeoutMs from '../dfTimeoutMs.mjs'
|
|
54
56
|
import extractJsonLoose from './extractJsonLoose.mjs'
|
|
55
57
|
|
|
56
58
|
|
|
@@ -70,13 +72,29 @@ import extractJsonLoose from './extractJsonLoose.mjs'
|
|
|
70
72
|
// 【防寫檔前綴】agentic CLI對cwd隔離免疫(會自行解析專案根目錄寫檔),
|
|
71
73
|
// 故預設在prompt前掛「禁止建檔」約束(實測有效); 不需要時傳promptPrefix:''關閉。
|
|
72
74
|
// 殷鑑: 2026-08-10執行任務歷史.md遭AI覆寫、評比腳本繞過前綴又產生根目錄孤兒檔。
|
|
75
|
+
//
|
|
76
|
+
// 措辭須豁免「唯讀查閱」(2026-08-13 A/B實測): 各CLI取得檔案內容的途徑不同——
|
|
77
|
+
// opencode與claude有獨立的read/grep工具, 不受「禁止執行指令」約束;
|
|
78
|
+
// 但codex讀檔即是執行shell指令, 舊措辭「禁止執行任何指令」對它等同「禁止讀檔」,
|
|
79
|
+
// 凡需讀專案的任務會得到一句「請貼上檔案內容」而非成果, 且該拒答是合法字串,
|
|
80
|
+
// 會通過驗證被遞補層當成「成功」, 整條fallback鏈就此停住——兜底地位被靜默廢掉。
|
|
81
|
+
// 實測: 舊措辭下codex回「無法讀取該檔案」, 改為下列措辭後正常讀檔作答(11.1s),
|
|
82
|
+
// 防副作用(建檔/改檔/刪檔/改動系統狀態)之本旨不變。
|
|
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']
|
|
73
90
|
|
|
74
91
|
|
|
75
|
-
//預設防寫檔前綴
|
|
92
|
+
//預設防寫檔前綴(禁副作用, 但豁免唯讀查閱——codex以shell讀檔, 一律禁指令等同禁讀檔)
|
|
76
93
|
let NO_SIDE_EFFECT = [
|
|
77
94
|
'【執行約束】你只需把結果輸出在回覆內容中。',
|
|
78
|
-
'
|
|
79
|
-
'
|
|
95
|
+
'禁止建立、修改或刪除任何檔案,也不要執行任何會改動磁碟或系統狀態的指令——',
|
|
96
|
+
'呼叫端只讀取你的回覆文字,任何寫入磁碟的動作都不會被採用,只會製造無人讀取的垃圾檔。',
|
|
97
|
+
'唯讀查閱(讀取檔案、搜尋內容、列出目錄)不在此限,需要時請照常使用。',
|
|
80
98
|
'', '',
|
|
81
99
|
].join('\n')
|
|
82
100
|
|
|
@@ -134,12 +152,13 @@ function buildChain(providers, spec) {
|
|
|
134
152
|
* @param {Function} [opt.parse=extractJsonLoose] 輸入回覆解析函數(stdout)=>Object|null,預設寬鬆JSON抽取
|
|
135
153
|
* @param {Boolean} [opt.rawText=false] 輸入是否以純文字模式運作布林值,true代表不解析JSON(json欄位為修剪後文字、check收文字),預設false
|
|
136
154
|
* @param {String} [opt.promptPrefix=防寫檔約束] 輸入prompt前綴字串,預設為防寫檔約束,傳''關閉
|
|
137
|
-
* @param {Number} [opt.timeoutMs=300000]
|
|
155
|
+
* @param {Number} [opt.timeoutMs=300000] 輸入單次嘗試逾時毫秒正整數,全套件統一預設300000
|
|
138
156
|
* @param {Number} [opt.budgetMs=null] 輸入整條遞補鏈之時間預算毫秒正整數,預設null代表不限
|
|
157
|
+
* @param {Number} [opt.minAttemptMs=20000] 輸入搭配budgetMs之開工門檻毫秒正整數,剩餘預算低於此值即不再開工,預設20000
|
|
139
158
|
* @param {Number} [opt.maxRetries=0] 輸入同家重試次數非負整數,預設0(韌性交給遞補;端點不穩偶發空回之模型可調高令同鍵重試)
|
|
140
159
|
* @param {String} [opt.cwd=process.cwd()] 輸入子進程工作目錄字串,預設process.cwd()
|
|
141
160
|
* @param {Object} [opt.store=null] 輸入游標持久化物件{get,set},預設null代表用行程內記憶體
|
|
142
|
-
* @param {Function} [opt.onEvent=null] 輸入遞補層事件回調函數,預設null
|
|
161
|
+
* @param {Function} [opt.onEvent=null] 輸入遞補層事件回調函數,預設null。除上列外之其餘鍵(retryDelayMs、maxBuffer、onStdout等)亦一律原樣轉傳dispatchAiFallback
|
|
143
162
|
* @returns {Promise} 回傳Promise,resolve回傳結果物件,內含ok(是否取得可用結果布林值)、json(解析後物件,rawText模式下為文字)、providerId(實際使用之名稱)、keyIndex、keyId、ms(總耗時毫秒)、tried(遞補嘗試歷程陣列)、error(錯誤訊息字串),本函數不會reject
|
|
144
163
|
* @example
|
|
145
164
|
* //need cli in system PATH
|
|
@@ -222,15 +241,12 @@ async function callAiWithFallback(prompt, opt = {}) {
|
|
|
222
241
|
return check ? check(j) === true : true
|
|
223
242
|
}
|
|
224
243
|
|
|
244
|
+
//剔除本層自用鍵後原樣轉傳(含minAttemptMs/retryDelayMs/maxBuffer等), providers與validate由本層給定
|
|
225
245
|
let r = await dispatchAiFallback(promptPrefix + prompt, {
|
|
246
|
+
...omit(opt, OWN_KEYS),
|
|
226
247
|
providers: chain,
|
|
227
248
|
validate,
|
|
228
|
-
timeoutMs: get(opt, 'timeoutMs', null) || 300000
|
|
229
|
-
budgetMs: get(opt, 'budgetMs', null) || undefined,
|
|
230
|
-
maxRetries: get(opt, 'maxRetries', null) || 0,
|
|
231
|
-
cwd: get(opt, 'cwd', null) || process.cwd(),
|
|
232
|
-
store: get(opt, 'store', null) || undefined,
|
|
233
|
-
onEvent: get(opt, 'onEvent', null) || undefined,
|
|
249
|
+
timeoutMs: get(opt, 'timeoutMs', null) || dfTimeoutMs, //全套件統一預設300000
|
|
234
250
|
})
|
|
235
251
|
|
|
236
252
|
//result, 已過validate故此處parse必然成功(同一解析器), 重解析僅為取出物件
|
|
@@ -269,7 +285,7 @@ export { buildChain, NO_SIDE_EFFECT }
|
|
|
269
285
|
<br class="clear">
|
|
270
286
|
|
|
271
287
|
<footer>
|
|
272
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
288
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026 12:30:07 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
273
289
|
</footer>
|
|
274
290
|
|
|
275
291
|
<script>prettyPrint();</script>
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
<nav >
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
<h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#WDispatchAi">WDispatchAi</a></li><li><a href="global.html#adapters">adapters</a></li><li><a href="global.html#buildChain">buildChain</a></li><li><a href="global.html#buildValidator">buildValidator</a></li><li><a href="global.html#callAiWithFallback">callAiWithFallback</a></li><li><a href="global.html#callOnce">callOnce</a></li><li><a href="global.html#defaultIntegratePrompt">defaultIntegratePrompt</a></li><li><a href="global.html#dispatchAi">dispatchAi</a></li><li><a href="global.html#dispatchAiFallback">dispatchAiFallback</a></li><li><a href="global.html#dispatchAiWkf">dispatchAiWkf</a></li><li><a href="global.html#dispatchAntigravity">dispatchAntigravity</a></li><li><a href="global.html#dispatchApiOpenaiCompat">dispatchApiOpenaiCompat</a></li><li><a href="global.html#dispatchClaude">dispatchClaude</a></li><li><a href="global.html#dispatchCodex">dispatchCodex</a></li><li><a href="global.html#dispatchOpencode">dispatchOpencode</a></li><li><a href="global.html#extractJsonLoose">extractJsonLoose</a></li><li><a href="global.html#getCliArgs">getCliArgs</a></li><li><a href="global.html#getErrorResult">getErrorResult</a></li><li><a href="global.html#isKeyIndependentFail">isKeyIndependentFail</a></li><li><a href="global.html#runFanout">runFanout</a></li><li><a href="global.html#runFanoutPipeline">runFanoutPipeline</a></li><li><a href="global.html#runRolePipeline">runRolePipeline</a></li></ul>
|
|
32
|
+
<h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#WDispatchAi">WDispatchAi</a></li><li><a href="global.html#adapters">adapters</a></li><li><a href="global.html#buildChain">buildChain</a></li><li><a href="global.html#buildValidator">buildValidator</a></li><li><a href="global.html#callAiWithFallback">callAiWithFallback</a></li><li><a href="global.html#callOnce">callOnce</a></li><li><a href="global.html#defaultIntegratePrompt">defaultIntegratePrompt</a></li><li><a href="global.html#dfTimeoutMs">dfTimeoutMs</a></li><li><a href="global.html#dispatchAi">dispatchAi</a></li><li><a href="global.html#dispatchAiFallback">dispatchAiFallback</a></li><li><a href="global.html#dispatchAiWkf">dispatchAiWkf</a></li><li><a href="global.html#dispatchAntigravity">dispatchAntigravity</a></li><li><a href="global.html#dispatchApiOpenaiCompat">dispatchApiOpenaiCompat</a></li><li><a href="global.html#dispatchClaude">dispatchClaude</a></li><li><a href="global.html#dispatchCodex">dispatchCodex</a></li><li><a href="global.html#dispatchOpencode">dispatchOpencode</a></li><li><a href="global.html#extractJsonLoose">extractJsonLoose</a></li><li><a href="global.html#getCliArgs">getCliArgs</a></li><li><a href="global.html#getErrorResult">getErrorResult</a></li><li><a href="global.html#isKeyIndependentFail">isKeyIndependentFail</a></li><li><a href="global.html#resolveProviders">resolveProviders</a></li><li><a href="global.html#runFanout">runFanout</a></li><li><a href="global.html#runFanoutPipeline">runFanoutPipeline</a></li><li><a href="global.html#runRolePipeline">runRolePipeline</a></li></ul>
|
|
33
33
|
|
|
34
34
|
</nav>
|
|
35
35
|
|
|
@@ -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
|
|
170
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026 12:30:07 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
171
171
|
</footer>
|
|
172
172
|
|
|
173
173
|
<script>prettyPrint();</script>
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
<nav >
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
<h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#WDispatchAi">WDispatchAi</a></li><li><a href="global.html#adapters">adapters</a></li><li><a href="global.html#buildChain">buildChain</a></li><li><a href="global.html#buildValidator">buildValidator</a></li><li><a href="global.html#callAiWithFallback">callAiWithFallback</a></li><li><a href="global.html#callOnce">callOnce</a></li><li><a href="global.html#defaultIntegratePrompt">defaultIntegratePrompt</a></li><li><a href="global.html#dispatchAi">dispatchAi</a></li><li><a href="global.html#dispatchAiFallback">dispatchAiFallback</a></li><li><a href="global.html#dispatchAiWkf">dispatchAiWkf</a></li><li><a href="global.html#dispatchAntigravity">dispatchAntigravity</a></li><li><a href="global.html#dispatchApiOpenaiCompat">dispatchApiOpenaiCompat</a></li><li><a href="global.html#dispatchClaude">dispatchClaude</a></li><li><a href="global.html#dispatchCodex">dispatchCodex</a></li><li><a href="global.html#dispatchOpencode">dispatchOpencode</a></li><li><a href="global.html#extractJsonLoose">extractJsonLoose</a></li><li><a href="global.html#getCliArgs">getCliArgs</a></li><li><a href="global.html#getErrorResult">getErrorResult</a></li><li><a href="global.html#isKeyIndependentFail">isKeyIndependentFail</a></li><li><a href="global.html#runFanout">runFanout</a></li><li><a href="global.html#runFanoutPipeline">runFanoutPipeline</a></li><li><a href="global.html#runRolePipeline">runRolePipeline</a></li></ul>
|
|
32
|
+
<h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#WDispatchAi">WDispatchAi</a></li><li><a href="global.html#adapters">adapters</a></li><li><a href="global.html#buildChain">buildChain</a></li><li><a href="global.html#buildValidator">buildValidator</a></li><li><a href="global.html#callAiWithFallback">callAiWithFallback</a></li><li><a href="global.html#callOnce">callOnce</a></li><li><a href="global.html#defaultIntegratePrompt">defaultIntegratePrompt</a></li><li><a href="global.html#dfTimeoutMs">dfTimeoutMs</a></li><li><a href="global.html#dispatchAi">dispatchAi</a></li><li><a href="global.html#dispatchAiFallback">dispatchAiFallback</a></li><li><a href="global.html#dispatchAiWkf">dispatchAiWkf</a></li><li><a href="global.html#dispatchAntigravity">dispatchAntigravity</a></li><li><a href="global.html#dispatchApiOpenaiCompat">dispatchApiOpenaiCompat</a></li><li><a href="global.html#dispatchClaude">dispatchClaude</a></li><li><a href="global.html#dispatchCodex">dispatchCodex</a></li><li><a href="global.html#dispatchOpencode">dispatchOpencode</a></li><li><a href="global.html#extractJsonLoose">extractJsonLoose</a></li><li><a href="global.html#getCliArgs">getCliArgs</a></li><li><a href="global.html#getErrorResult">getErrorResult</a></li><li><a href="global.html#isKeyIndependentFail">isKeyIndependentFail</a></li><li><a href="global.html#resolveProviders">resolveProviders</a></li><li><a href="global.html#runFanout">runFanout</a></li><li><a href="global.html#runFanoutPipeline">runFanoutPipeline</a></li><li><a href="global.html#runRolePipeline">runRolePipeline</a></li></ul>
|
|
33
33
|
|
|
34
34
|
</nav>
|
|
35
35
|
|
|
@@ -214,7 +214,7 @@ export { defaultIntegratePrompt }
|
|
|
214
214
|
<br class="clear">
|
|
215
215
|
|
|
216
216
|
<footer>
|
|
217
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
217
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026 12:30:07 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
218
218
|
</footer>
|
|
219
219
|
|
|
220
220
|
<script>prettyPrint();</script>
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
<nav >
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
<h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#WDispatchAi">WDispatchAi</a></li><li><a href="global.html#adapters">adapters</a></li><li><a href="global.html#buildChain">buildChain</a></li><li><a href="global.html#buildValidator">buildValidator</a></li><li><a href="global.html#callAiWithFallback">callAiWithFallback</a></li><li><a href="global.html#callOnce">callOnce</a></li><li><a href="global.html#defaultIntegratePrompt">defaultIntegratePrompt</a></li><li><a href="global.html#dispatchAi">dispatchAi</a></li><li><a href="global.html#dispatchAiFallback">dispatchAiFallback</a></li><li><a href="global.html#dispatchAiWkf">dispatchAiWkf</a></li><li><a href="global.html#dispatchAntigravity">dispatchAntigravity</a></li><li><a href="global.html#dispatchApiOpenaiCompat">dispatchApiOpenaiCompat</a></li><li><a href="global.html#dispatchClaude">dispatchClaude</a></li><li><a href="global.html#dispatchCodex">dispatchCodex</a></li><li><a href="global.html#dispatchOpencode">dispatchOpencode</a></li><li><a href="global.html#extractJsonLoose">extractJsonLoose</a></li><li><a href="global.html#getCliArgs">getCliArgs</a></li><li><a href="global.html#getErrorResult">getErrorResult</a></li><li><a href="global.html#isKeyIndependentFail">isKeyIndependentFail</a></li><li><a href="global.html#runFanout">runFanout</a></li><li><a href="global.html#runFanoutPipeline">runFanoutPipeline</a></li><li><a href="global.html#runRolePipeline">runRolePipeline</a></li></ul>
|
|
32
|
+
<h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#WDispatchAi">WDispatchAi</a></li><li><a href="global.html#adapters">adapters</a></li><li><a href="global.html#buildChain">buildChain</a></li><li><a href="global.html#buildValidator">buildValidator</a></li><li><a href="global.html#callAiWithFallback">callAiWithFallback</a></li><li><a href="global.html#callOnce">callOnce</a></li><li><a href="global.html#defaultIntegratePrompt">defaultIntegratePrompt</a></li><li><a href="global.html#dfTimeoutMs">dfTimeoutMs</a></li><li><a href="global.html#dispatchAi">dispatchAi</a></li><li><a href="global.html#dispatchAiFallback">dispatchAiFallback</a></li><li><a href="global.html#dispatchAiWkf">dispatchAiWkf</a></li><li><a href="global.html#dispatchAntigravity">dispatchAntigravity</a></li><li><a href="global.html#dispatchApiOpenaiCompat">dispatchApiOpenaiCompat</a></li><li><a href="global.html#dispatchClaude">dispatchClaude</a></li><li><a href="global.html#dispatchCodex">dispatchCodex</a></li><li><a href="global.html#dispatchOpencode">dispatchOpencode</a></li><li><a href="global.html#extractJsonLoose">extractJsonLoose</a></li><li><a href="global.html#getCliArgs">getCliArgs</a></li><li><a href="global.html#getErrorResult">getErrorResult</a></li><li><a href="global.html#isKeyIndependentFail">isKeyIndependentFail</a></li><li><a href="global.html#resolveProviders">resolveProviders</a></li><li><a href="global.html#runFanout">runFanout</a></li><li><a href="global.html#runFanoutPipeline">runFanoutPipeline</a></li><li><a href="global.html#runRolePipeline">runRolePipeline</a></li></ul>
|
|
33
33
|
|
|
34
34
|
</nav>
|
|
35
35
|
|
|
@@ -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
|
|
168
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026 12:30:07 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
169
169
|
</footer>
|
|
170
170
|
|
|
171
171
|
<script>prettyPrint();</script>
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
<nav >
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
<h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#WDispatchAi">WDispatchAi</a></li><li><a href="global.html#adapters">adapters</a></li><li><a href="global.html#buildChain">buildChain</a></li><li><a href="global.html#buildValidator">buildValidator</a></li><li><a href="global.html#callAiWithFallback">callAiWithFallback</a></li><li><a href="global.html#callOnce">callOnce</a></li><li><a href="global.html#defaultIntegratePrompt">defaultIntegratePrompt</a></li><li><a href="global.html#dispatchAi">dispatchAi</a></li><li><a href="global.html#dispatchAiFallback">dispatchAiFallback</a></li><li><a href="global.html#dispatchAiWkf">dispatchAiWkf</a></li><li><a href="global.html#dispatchAntigravity">dispatchAntigravity</a></li><li><a href="global.html#dispatchApiOpenaiCompat">dispatchApiOpenaiCompat</a></li><li><a href="global.html#dispatchClaude">dispatchClaude</a></li><li><a href="global.html#dispatchCodex">dispatchCodex</a></li><li><a href="global.html#dispatchOpencode">dispatchOpencode</a></li><li><a href="global.html#extractJsonLoose">extractJsonLoose</a></li><li><a href="global.html#getCliArgs">getCliArgs</a></li><li><a href="global.html#getErrorResult">getErrorResult</a></li><li><a href="global.html#isKeyIndependentFail">isKeyIndependentFail</a></li><li><a href="global.html#runFanout">runFanout</a></li><li><a href="global.html#runFanoutPipeline">runFanoutPipeline</a></li><li><a href="global.html#runRolePipeline">runRolePipeline</a></li></ul>
|
|
32
|
+
<h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#WDispatchAi">WDispatchAi</a></li><li><a href="global.html#adapters">adapters</a></li><li><a href="global.html#buildChain">buildChain</a></li><li><a href="global.html#buildValidator">buildValidator</a></li><li><a href="global.html#callAiWithFallback">callAiWithFallback</a></li><li><a href="global.html#callOnce">callOnce</a></li><li><a href="global.html#defaultIntegratePrompt">defaultIntegratePrompt</a></li><li><a href="global.html#dfTimeoutMs">dfTimeoutMs</a></li><li><a href="global.html#dispatchAi">dispatchAi</a></li><li><a href="global.html#dispatchAiFallback">dispatchAiFallback</a></li><li><a href="global.html#dispatchAiWkf">dispatchAiWkf</a></li><li><a href="global.html#dispatchAntigravity">dispatchAntigravity</a></li><li><a href="global.html#dispatchApiOpenaiCompat">dispatchApiOpenaiCompat</a></li><li><a href="global.html#dispatchClaude">dispatchClaude</a></li><li><a href="global.html#dispatchCodex">dispatchCodex</a></li><li><a href="global.html#dispatchOpencode">dispatchOpencode</a></li><li><a href="global.html#extractJsonLoose">extractJsonLoose</a></li><li><a href="global.html#getCliArgs">getCliArgs</a></li><li><a href="global.html#getErrorResult">getErrorResult</a></li><li><a href="global.html#isKeyIndependentFail">isKeyIndependentFail</a></li><li><a href="global.html#resolveProviders">resolveProviders</a></li><li><a href="global.html#runFanout">runFanout</a></li><li><a href="global.html#runFanoutPipeline">runFanoutPipeline</a></li><li><a href="global.html#runRolePipeline">runRolePipeline</a></li></ul>
|
|
33
33
|
|
|
34
34
|
</nav>
|
|
35
35
|
|
|
@@ -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
|
|
185
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Fri Aug 14 2026 12:30:07 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/g.mjs
CHANGED
|
@@ -112,7 +112,7 @@ let test = async () => {
|
|
|
112
112
|
providers: [
|
|
113
113
|
//REST版排前面: 免CLI、快3~5倍, 純文字任務優先走此路
|
|
114
114
|
{
|
|
115
|
-
id: '
|
|
115
|
+
id: 'agnes:agnes-2.0-flash',
|
|
116
116
|
kind: 'api-openai-compat',
|
|
117
117
|
baseURL: 'https://apihub.agnes-ai.com/v1',
|
|
118
118
|
model: 'agnes-2.0-flash',
|
|
@@ -137,12 +137,12 @@ let test = async () => {
|
|
|
137
137
|
})
|
|
138
138
|
console.log('fallback:', r7.ok, r7.providerId, r7.keyIndex, r7.stdout.trim())
|
|
139
139
|
console.log('tried:', r7.tried.map((x) => `${x.keyId}:${x.outcome}`).join(', '))
|
|
140
|
-
// => event: try
|
|
141
|
-
// => event: next-key
|
|
142
|
-
// => event: try
|
|
143
|
-
// => event: ok
|
|
144
|
-
// => fallback: true
|
|
145
|
-
// => tried:
|
|
140
|
+
// => event: try agnes:agnes-2.0-flash#0
|
|
141
|
+
// => event: next-key agnes:agnes-2.0-flash#0 HTTP 401
|
|
142
|
+
// => event: try agnes:agnes-2.0-flash#1
|
|
143
|
+
// => event: ok agnes:agnes-2.0-flash#1
|
|
144
|
+
// => fallback: true agnes:agnes-2.0-flash 1 完成
|
|
145
|
+
// => tried: agnes:agnes-2.0-flash#0:next-key, agnes:agnes-2.0-flash#1:ok
|
|
146
146
|
|
|
147
147
|
}
|
|
148
148
|
await test()
|
package/package.json
CHANGED
package/src/WDispatchAi.mjs
CHANGED
|
@@ -8,6 +8,8 @@ import dispatchClaude from './dispatchClaude.mjs'
|
|
|
8
8
|
import dispatchCodex from './dispatchCodex.mjs'
|
|
9
9
|
import dispatchAntigravity from './dispatchAntigravity.mjs'
|
|
10
10
|
import dispatchApiOpenaiCompat from './dispatchApiOpenaiCompat.mjs'
|
|
11
|
+
import providers from './providers.mjs'
|
|
12
|
+
import resolveProviders from './resolveProviders.mjs'
|
|
11
13
|
|
|
12
14
|
|
|
13
15
|
// WDispatchAi.mjs — AI供應商分派層
|
|
@@ -24,10 +26,10 @@ let KINDS = keys(adapters)
|
|
|
24
26
|
/**
|
|
25
27
|
* AI供應商分派
|
|
26
28
|
*
|
|
27
|
-
* @returns {Object} 回傳物件,其內含KINDS(可用供應商種類字串陣列),dispatchAiWkf
|
|
29
|
+
* @returns {Object} 回傳物件,其內含KINDS(可用供應商種類字串陣列),dispatchAiWkf之工作流工廠函數,dispatchAi、dispatchAiFallback、dispatchOpencode、dispatchClaude、dispatchCodex、dispatchAntigravity、dispatchApiOpenaiCompat之async函數,以及providers(預設providers定義檔)與resolveProviders(envVar展開器)
|
|
28
30
|
* @example
|
|
29
31
|
*
|
|
30
|
-
* 詳見dispatchAi、dispatchAiFallback、dispatchAiWkf、dispatchOpencode、dispatchClaude、dispatchCodex、dispatchAntigravity、dispatchApiOpenaiCompat範例
|
|
32
|
+
* 詳見dispatchAi、dispatchAiFallback、dispatchAiWkf、dispatchOpencode、dispatchClaude、dispatchCodex、dispatchAntigravity、dispatchApiOpenaiCompat、resolveProviders範例
|
|
31
33
|
*
|
|
32
34
|
*/
|
|
33
35
|
let WDispatchAi = {
|
|
@@ -40,6 +42,8 @@ let WDispatchAi = {
|
|
|
40
42
|
dispatchCodex,
|
|
41
43
|
dispatchAntigravity,
|
|
42
44
|
dispatchApiOpenaiCompat,
|
|
45
|
+
providers,
|
|
46
|
+
resolveProviders,
|
|
43
47
|
}
|
|
44
48
|
|
|
45
49
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// dfTimeoutMs.mjs — 全套件統一之預設逾時毫秒(單一來源)
|
|
2
|
+
//
|
|
3
|
+
// 【為何統一】各轉接器與各層若各有預設(曾為CLI 120s/agy 300s/api 120s),
|
|
4
|
+
// 呼叫方難以理解為何不一致; 統一後呼叫方只需記一個數字, 要改就由opt傳入覆寫。
|
|
5
|
+
//
|
|
6
|
+
// 【為何取300000(5分鐘)】對齊agy自身print-timeout之預設5m0s;
|
|
7
|
+
// agy為agent型CLI, 實測合法執行可達116秒, 統一成120秒會誤殺;
|
|
8
|
+
// 快速任務有需要可自行下調, 複雜任務(如單一AI工作15分鐘)依README之Timeout規劃上調。
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 全套件統一之預設逾時毫秒
|
|
13
|
+
*
|
|
14
|
+
* @returns {Number} 回傳預設逾時毫秒整數300000(5分鐘)
|
|
15
|
+
* @example
|
|
16
|
+
*
|
|
17
|
+
* import dfTimeoutMs from './src/dfTimeoutMs.mjs'
|
|
18
|
+
*
|
|
19
|
+
* console.log(dfTimeoutMs)
|
|
20
|
+
* // => 300000
|
|
21
|
+
*
|
|
22
|
+
*/
|
|
23
|
+
let dfTimeoutMs = 300000
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
export default dfTimeoutMs
|
|
@@ -8,6 +8,7 @@ import ispint from 'wsemi/src/ispint.mjs'
|
|
|
8
8
|
import cint from 'wsemi/src/cint.mjs'
|
|
9
9
|
import dispatchAi from './dispatchAi.mjs'
|
|
10
10
|
import getErrorResult from './getErrorResult.mjs'
|
|
11
|
+
import dfTimeoutMs from './dfTimeoutMs.mjs'
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
// dispatchAiFallback.mjs — 多供應商自動遞補層
|
|
@@ -39,10 +40,12 @@ import getErrorResult from './getErrorResult.mjs'
|
|
|
39
40
|
// ✗ id:'claude' —— 日後要同時掛sonnet與opus就無法並存, 且日誌看不出用了哪個模型
|
|
40
41
|
// ✓ id:'claude:sonnet' / id:'claude:opus'
|
|
41
42
|
//
|
|
42
|
-
// ② 同一模型經不同路徑取得時, id
|
|
43
|
+
// ② 同一模型經不同路徑取得時, id須帶上路徑, 且前綴用「具體路徑名」不用泛稱
|
|
43
44
|
// 同一個laguna可經Poolside官方REST、OpenRouter、opencode CLI三條路,
|
|
44
45
|
// 三者額度池與故障域各自獨立, 屬三個供應商:
|
|
45
46
|
// ✓ 'poolside:laguna-s-2.1' / 'or:poolside/laguna-s-2.1:free' / 'oc:poolside/poolside/laguna-s-2.1'
|
|
47
|
+
// ✗ 'api:laguna-s-2.1' —— 泛稱api:在同模型有多個REST閘道時會撞名, 且日誌看不出走哪個閘道
|
|
48
|
+
// 慣用前綴: CLI類=oc:/agy:/claude:/codex:(即kind或CLI名); REST類=閘道名(zen:/agnes:/poolside:/or:/nv:)
|
|
46
49
|
//
|
|
47
50
|
// ③ id務必給且務必唯一
|
|
48
51
|
// 未給時本套件回退為「陣列索引字串」——索引是位置不是身分, 日後於鏈中插入條目
|
|
@@ -66,7 +69,7 @@ let ENTRY_KEYS = ['id', 'keys']
|
|
|
66
69
|
|
|
67
70
|
//預設值
|
|
68
71
|
let DEFAULT_MIN_ATTEMPT_MS = 20000
|
|
69
|
-
let DEFAULT_TIMEOUT_MS =
|
|
72
|
+
let DEFAULT_TIMEOUT_MS = dfTimeoutMs //全套件統一預設300000
|
|
70
73
|
|
|
71
74
|
|
|
72
75
|
//memoryState, 未注入store時之行程內預設狀態(跨呼叫有效, 重啟歸零)
|
|
@@ -137,11 +140,11 @@ function isKeyIndependentFail(r) {
|
|
|
137
140
|
* @param {Number} [opt.budgetMs=null] 輸入整輪遞補之時間上限毫秒正整數,剩餘預算會壓進每次呼叫之timeoutMs,預設null代表不限
|
|
138
141
|
* @param {Number} [opt.minAttemptMs=20000] 輸入單次嘗試之最低剩餘預算毫秒正整數,剩餘低於此值即停止嘗試回報budget exhausted,預設20000
|
|
139
142
|
* @param {Object} [opt.store=null] 輸入狀態持久化物件{get:()=>state,set:(state)=>{}},state內含cursors(逐群組游標),省略代表用行程內記憶體(跨呼叫有效,重啟歸零)。假定單行程序列調用,並行請自行加鎖
|
|
140
|
-
* @param {Function} [opt.onEvent=null] 輸入事件回調函數(ev)=>{},ev.type可為'try'、'ok'、'next-key'、'skip-group'、'budget-out'
|
|
141
|
-
* @param {Number} [opt.timeoutMs=
|
|
143
|
+
* @param {Function} [opt.onEvent=null] 輸入事件回調函數(ev)=>{},ev.type可為'try'、'ok'、'next-key'、'skip-group'、'budget-out';失敗事件(next-key/skip-group)另帶stdout(被拒回覆)與stderr(錯誤輸出)供診斷,兩者於失敗路徑已由轉接器截斷;回調拋出例外不影響主流程,預設null
|
|
144
|
+
* @param {Number} [opt.timeoutMs=300000] 輸入各attempt共用之逾時毫秒正整數,條目可覆寫,全套件統一預設300000
|
|
142
145
|
* @param {String|Function} [opt.validate=undefined] 輸入各attempt共用之stdout驗證規則,條目可覆寫,預設undefined
|
|
143
146
|
* @param {Number} [opt.maxRetries=0] 輸入各attempt共用之同家重試次數非負整數,韌性建議交給換家而非重試同一家,預設0
|
|
144
|
-
* @returns {Promise} 回傳Promise,resolve回傳結果物件,除execCli既有欄位(ok、stdout、stderr、code、error、durationMs、attempts、pid)外,追加providerId(實際使用之群組)、keyIndex(實際使用之金鑰索引,無keys時為null)、kind、model、tried(
|
|
147
|
+
* @returns {Promise} 回傳Promise,resolve回傳結果物件,除execCli既有欄位(ok、stdout、stderr、code、error、durationMs、attempts、pid)外,追加providerId(實際使用之群組)、keyIndex(實際使用之金鑰索引,無keys時為null)、kind、model、tried(全部嘗試歷程陣列,成功時亦回傳;失敗項含stdout與stderr供診斷被拒原因),本函數不會reject
|
|
145
148
|
* @example
|
|
146
149
|
* //need opencode, claude, codex cli in system PATH
|
|
147
150
|
*
|
|
@@ -342,18 +345,20 @@ async function dispatchAiFallback(prompt, opt = {}) {
|
|
|
342
345
|
//失敗分流
|
|
343
346
|
lastResult = r
|
|
344
347
|
lastMeta = { providerId: id, keyIndex, kind, model }
|
|
348
|
+
//失敗事件與tried一併帶被拒回覆(stdout)與錯誤輸出(stderr), 供呼叫端診斷失敗原因
|
|
349
|
+
//(如驗證失敗時模型究竟回了什麼); 兩者於失敗路徑已由轉接器截斷(≤500/1000字元), 不會過大
|
|
345
350
|
if (isKeyIndependentFail(r)) {
|
|
346
351
|
|
|
347
352
|
//與金鑰無關, 整組跳過
|
|
348
|
-
emit({ type: 'skip-group', providerId: id, keyIndex, keyId, error: r.error })
|
|
349
|
-
tried.push({ providerId: id, keyIndex, keyId, outcome: 'skip-group', error: r.error, durationMs: r.durationMs })
|
|
353
|
+
emit({ type: 'skip-group', providerId: id, keyIndex, keyId, error: r.error, stdout: r.stdout, stderr: r.stderr })
|
|
354
|
+
tried.push({ providerId: id, keyIndex, keyId, outcome: 'skip-group', error: r.error, stdout: r.stdout, stderr: r.stderr, durationMs: r.durationMs })
|
|
350
355
|
skipGroup = true
|
|
351
356
|
}
|
|
352
357
|
else {
|
|
353
358
|
|
|
354
359
|
//其餘(含額度上限/金鑰無效/未分類), 換組內下一把, 不記憶不停用
|
|
355
|
-
emit({ type: 'next-key', providerId: id, keyIndex, keyId, error: r.error })
|
|
356
|
-
tried.push({ providerId: id, keyIndex, keyId, outcome: 'next-key', error: r.error, durationMs: r.durationMs })
|
|
360
|
+
emit({ type: 'next-key', providerId: id, keyIndex, keyId, error: r.error, stdout: r.stdout, stderr: r.stderr })
|
|
361
|
+
tried.push({ providerId: id, keyIndex, keyId, outcome: 'next-key', error: r.error, stdout: r.stdout, stderr: r.stderr, durationMs: r.durationMs })
|
|
357
362
|
}
|
|
358
363
|
|
|
359
364
|
}
|