w-dispatch-ai 1.0.23 → 1.0.25
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 +1 -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/budgetFor.mjs.html +1 -1
- package/docs/buildValidator.mjs.html +1 -1
- package/docs/castPintOr.mjs.html +1 -1
- package/docs/dfTimeoutMs.mjs.html +1 -1
- package/docs/dispatchAi.mjs.html +1 -1
- package/docs/dispatchAiFallback.mjs.html +1 -1
- package/docs/dispatchAiWkf.mjs.html +1 -1
- package/docs/dispatchAntigravity.mjs.html +1 -1
- package/docs/dispatchApiOpenaiCompat.mjs.html +1 -1
- package/docs/dispatchApiOpenaiResponses.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/getErrorType.mjs.html +1 -1
- package/docs/global.html +3 -42
- package/docs/index.html +1 -1
- package/docs/quota_dfQuotaTimeoutMs.mjs.html +1 -1
- package/docs/quota_fetchQuotaJson.mjs.html +1 -1
- package/docs/quota_fromCodexUsageHttp.mjs.html +1 -1
- package/docs/quota_getQuotaAntigravity.mjs.html +1 -1
- package/docs/quota_getQuotaClaude.mjs.html +1 -1
- package/docs/quota_getQuotaCodex.mjs.html +1 -1
- package/docs/quota_readJsonOrNull.mjs.html +1 -1
- package/docs/quota_toQuotaLabel.mjs.html +1 -1
- package/docs/quota_toQuotaResult.mjs.html +1 -1
- package/docs/quota_toQuotaScopedLabel.mjs.html +1 -1
- package/docs/quota_toQuotaWindow.mjs.html +1 -1
- package/docs/readEnvFile.mjs.html +61 -61
- package/docs/resolveProviders.mjs.html +182 -182
- package/docs/wkf_callAiWithFallback.mjs.html +1 -1
- package/docs/wkf_createFileStore.mjs.html +1 -1
- package/docs/wkf_createUsageCounter.mjs.html +1 -1
- package/docs/wkf_extractJsonLoose.mjs.html +1 -1
- package/docs/wkf_noSideEffectPrefix.mjs.html +1 -1
- package/docs/wkf_runFanout.mjs.html +1 -1
- package/docs/wkf_runFanoutPipeline.mjs.html +1 -1
- package/docs/wkf_runRolePipeline.mjs.html +1 -1
- package/docs/wkf_salvageTruncatedArray.mjs.html +1 -1
- package/package.json +4 -9
- package/src/providers.mjs +305 -303
- package/src/readEnvFile.mjs +60 -60
- package/src/resolveProviders.mjs +181 -181
|
@@ -45,187 +45,187 @@
|
|
|
45
45
|
|
|
46
46
|
<section>
|
|
47
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
|
-
import strFindSimilar from 'wsemi/src/strFindSimilar.mjs'
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
// resolveProviders.mjs — 把providers定義檔展開為可直接使用的條目
|
|
58
|
-
//
|
|
59
|
-
// 【為何需要】providers.mjs之條目以envVar間接引用金鑰(機密不落設定檔, 只寫變數名),
|
|
60
|
-
// 而dispatchAiFallback只認keys陣列——本函數負責envVar → keys之展開,
|
|
61
|
-
// 缺對應環境變數者停用該條目並列入skipped回報(不中斷、不throw),
|
|
62
|
-
// 訂閱登入態條目(claude/codex等無envVar)原樣通過。
|
|
63
|
-
//
|
|
64
|
-
// 【自選】opt.pick給id陣列即可只取用部分條目, 且依pick之順序回傳
|
|
65
|
-
// (順序即dispatchAiFallback之優先序); 查無之id列入missing回報。
|
|
66
|
-
//
|
|
67
|
-
// 【後處理單一入口: opt.exes與opt.patch】消費端常需於展開後對條目做兩類覆寫:
|
|
68
|
-
// ①逐kind注入CLI執行檔絕對路徑(Windows排程於session 0執行時PATH可能不含npm
|
|
69
|
-
// 全域目錄, 靠指令名會ENOENT); ②逐id覆寫任意欄位(如各家實測耗時相差近10倍,
|
|
70
|
-
// timeoutMs須逐條指定)。此前只能於呼叫端自行map, 而陣列版(providers)與表格版
|
|
71
|
-
// (table)若各自後處理, 極易只套用其一——使用端殷鑑(2026-08-14): 逐條timeout
|
|
72
|
-
// 只加在陣列版, 工作流走表格版全部落回全域預設而不自知。後處理收進本函數,
|
|
73
|
-
// 兩種輸出同源產出, 結構性杜絕單邊套用。
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* 展開providers定義條目:envVar → keys,並可依id自選子集
|
|
78
|
-
*
|
|
79
|
-
* 特點:
|
|
80
|
-
* 條目之envVar依env來源(預設process.env)展開為keys陣列(變數值以逗號分隔多把),envVar欄位自輸出移除;
|
|
81
|
-
* 缺對應環境變數(或值為空)之條目停用並列入skipped,不中斷不throw;
|
|
82
|
-
* 無envVar之條目(訂閱登入態CLI)原樣通過;條目已自帶有效keys者以keys為準;
|
|
83
|
-
* opt.pick可依id自選子集並以pick順序回傳(順序即遞補優先序);
|
|
84
|
-
* opt.exes依kind注入CLI執行檔路徑、opt.patch依id淺合併覆寫欄位——皆於展開後施作,
|
|
85
|
-
* providers與table同源產出故必然一致;
|
|
86
|
-
* 輸入陣列與條目皆不被改動(輸出為淺拷貝)
|
|
87
|
-
*
|
|
88
|
-
* @param {Array} providers 輸入providers條目物件陣列(如providers.mjs之預設匯出)
|
|
89
|
-
* @param {Object} [opt={}] 輸入設定物件,預設{}
|
|
90
|
-
* @param {Object} [opt.env=process.env] 輸入金鑰來源物件(變數名 → 逗號分隔之金鑰字串),預設process.env。建議以readEnvFile('./.env')讀成物件傳入,不污染process.env
|
|
91
|
-
* @param {Array} [opt.pick=null] 輸入自選id字串陣列,依此順序回傳對應條目,查無之id列入missing,預設null代表全取(依原順序)
|
|
92
|
-
* @param {Object} [opt.exes=null] 輸入kind對執行檔絕對路徑之物件(如{claude:'C:/.../claude.exe'}),命中kind之條目補上exe欄位(條目已自帶exe者不覆寫——條目層設定優先),預設null代表不注入
|
|
93
|
-
* @param {Object} [opt.patch=null] 輸入id對部分欄位之物件(如{'claude:sonnet':{timeoutMs:360000}}),命中id之條目淺合併覆寫,於exes之後施作故可覆寫exe,預設null代表不覆寫
|
|
94
|
-
* @returns {Object} 回傳物件,內含providers(可直接餵dispatchAiFallback之條目陣列)、table(id對條目之物件,可直接餵dispatchAiWkf)、skipped(缺環境變數而停用之{id,envVar}陣列)、missing(pick查無之id字串陣列)、hints(missing id對最接近可用id之拼寫提示物件,pick查無多半是打錯字,附最接近id供直接定位;僅為相似度最高者非保證正解,無missing時為空物件)
|
|
95
|
-
* @example
|
|
96
|
-
*
|
|
97
|
-
* import resolveProviders from './src/resolveProviders.mjs'
|
|
98
|
-
* import readEnvFile from './src/readEnvFile.mjs'
|
|
99
|
-
* import providersAll from './src/providers.mjs'
|
|
100
|
-
*
|
|
101
|
-
* //金鑰放.env(變數值以逗號分隔多把), 以readEnvFile讀成物件, 不污染process.env
|
|
102
|
-
* let env = readEnvFile('./.env')
|
|
103
|
-
*
|
|
104
|
-
* //全取: envVar展開為keys, 缺環境變數者列入skipped
|
|
105
|
-
* let { providers, table, skipped } = resolveProviders(providersAll, { env })
|
|
106
|
-
* console.log(providers.length, skipped)
|
|
107
|
-
* // => 17 []
|
|
108
|
-
*
|
|
109
|
-
* //pick打錯字時, missing附拼寫提示hints(最接近之可用id)
|
|
110
|
-
* let rm = resolveProviders(providersAll, { env, pick: ['poolside/laguna-s-2.1'] })
|
|
111
|
-
* console.log(rm.missing, rm.hints)
|
|
112
|
-
* // => [ 'poolside/laguna-s-2.1' ] { 'poolside/laguna-s-2.1': 'poolside:laguna-s-2.1' }
|
|
113
|
-
*
|
|
114
|
-
* //自選: 依pick順序回傳(順序即遞補優先序), 可直接餵dispatchAiFallback
|
|
115
|
-
* let r2 = resolveProviders(providersAll, { env, pick: ['agnes:agnes-
|
|
116
|
-
* console.log(r2.providers.map((p) => p.id))
|
|
117
|
-
* // => [ 'agnes:agnes-
|
|
118
|
-
*
|
|
119
|
-
* //後處理: exes逐kind注入執行檔、patch逐id覆寫欄位, 陣列與table同步生效
|
|
120
|
-
* let r3 = resolveProviders(providersAll, {
|
|
121
|
-
* env,
|
|
122
|
-
* pick: ['agnes:agnes-
|
|
123
|
-
* exes: { claude: 'C:/Users/x/.local/bin/claude.exe' },
|
|
124
|
-
* patch: { 'claude:sonnet': { timeoutMs: 360000 } },
|
|
125
|
-
* })
|
|
126
|
-
* console.log(r3.table['claude:sonnet'].exe, r3.table['claude:sonnet'].timeoutMs)
|
|
127
|
-
* // => 'C:/Users/x/.local/bin/claude.exe' 360000
|
|
128
|
-
*
|
|
129
|
-
* //table可直接餵dispatchAiWkf之providers定義表
|
|
130
|
-
* //let wkf = dispatchAiWkf({ providers: r2.table, defaults: { timeoutMs: 1200000 } })
|
|
131
|
-
*
|
|
132
|
-
*/
|
|
133
|
-
function resolveProviders(providers, opt = {}) {
|
|
134
|
-
|
|
135
|
-
//env, 無效回退process.env(瀏覽器環境無process則空物件)
|
|
136
|
-
let env = get(opt, 'env', null)
|
|
137
|
-
if (!isobj(env)) {
|
|
138
|
-
env = (typeof process !== 'undefined' && process && isobj(process.env)) ? process.env : {}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
//providersRaw
|
|
142
|
-
let providersRaw = isarr(providers) ? providers.filter(isobj) : []
|
|
143
|
-
|
|
144
|
-
//pick, 依id自選並依pick順序回傳
|
|
145
|
-
let pick = get(opt, 'pick', null)
|
|
146
|
-
let missing = []
|
|
147
|
-
let selected = providersRaw
|
|
148
|
-
if (isearr(pick)) {
|
|
149
|
-
selected = []
|
|
150
|
-
for (let id of pick) {
|
|
151
|
-
let entry = providersRaw.find((p) => get(p, 'id', null) === id)
|
|
152
|
-
if (entry) {
|
|
153
|
-
selected.push(entry)
|
|
154
|
-
}
|
|
155
|
-
else {
|
|
156
|
-
missing.push(String(id))
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
//hints, missing之拼寫提示: 自全部條目id中找最接近者——實務上pick查無多半是打錯字
|
|
162
|
-
//(如'poolside/laguna'誤作分隔符), 附上最接近id可直接定位; 僅為相似度最高者, 非保證正解
|
|
163
|
-
let hints = {}
|
|
164
|
-
if (missing.length > 0) {
|
|
165
|
-
let ids = providersRaw.map((p) => get(p, 'id', null)).filter(isestr)
|
|
166
|
-
for (let mid of missing) {
|
|
167
|
-
hints[mid] = (ids.length > 0) ? get(strFindSimilar(mid, ids), 'bestMatch.target', null) : null
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
//展開envVar → keys
|
|
172
|
-
let out = []
|
|
173
|
-
let skipped = []
|
|
174
|
-
for (let entry of selected) {
|
|
175
|
-
let envVar = get(entry, 'envVar', null)
|
|
176
|
-
|
|
177
|
-
//無envVar(訂閱登入態CLI)或已自帶有效keys, 原樣通過(僅移除envVar欄位)
|
|
178
|
-
if (!isestr(envVar) || isearr(get(entry, 'keys', null))) {
|
|
179
|
-
out.push(omit(entry, ['envVar']))
|
|
180
|
-
continue
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
//envVar → keys, 變數值以逗號分隔多把
|
|
184
|
-
let keys = String(get(env, envVar, '') || '').split(',').map((k) => k.trim()).filter(Boolean)
|
|
185
|
-
if (keys.length === 0) {
|
|
186
|
-
|
|
187
|
-
//缺環境變數: 停用該條目並回報, 不中斷(設計providers原則§四.4)
|
|
188
|
-
skipped.push({ id: get(entry, 'id', ''), envVar })
|
|
189
|
-
continue
|
|
190
|
-
}
|
|
191
|
-
out.push({ ...omit(entry, ['envVar']), keys })
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
//後處理: exes(逐kind)與patch(逐id), 於table組建「之前」施作——
|
|
195
|
-
//providers與table由同一份out產出, 兩種輸出必然一致(檔頭之單邊套用殷鑑)
|
|
196
|
-
let exes = get(opt, 'exes', null)
|
|
197
|
-
let patch = get(opt, 'patch', null)
|
|
198
|
-
if (isobj(exes) || isobj(patch)) {
|
|
199
|
-
out = out.map((entry) => {
|
|
200
|
-
let e = entry
|
|
201
|
-
|
|
202
|
-
//exes: 條目已自帶exe者不覆寫(條目層設定優先於全域注入)
|
|
203
|
-
let exe = isobj(exes) ? get(exes, get(e, 'kind', ''), null) : null
|
|
204
|
-
if (isestr(exe) && !isestr(get(e, 'exe', null))) {
|
|
205
|
-
e = { ...e, exe }
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
//patch: 依id淺合併, 於exes之後施作故可覆寫exe
|
|
209
|
-
let pt = isobj(patch) ? get(patch, get(e, 'id', ''), null) : null
|
|
210
|
-
if (isobj(pt)) {
|
|
211
|
-
e = { ...e, ...pt }
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
return e
|
|
215
|
-
})
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
//table, id → 條目, 可直接作dispatchAiWkf之providers定義表
|
|
219
|
-
let table = {}
|
|
220
|
-
for (let entry of out) {
|
|
221
|
-
table[entry.id] = entry
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
return { providers: out, table, skipped, missing, hints }
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
export default resolveProviders
|
|
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
|
+
import strFindSimilar from 'wsemi/src/strFindSimilar.mjs'
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
// resolveProviders.mjs — 把providers定義檔展開為可直接使用的條目
|
|
58
|
+
//
|
|
59
|
+
// 【為何需要】providers.mjs之條目以envVar間接引用金鑰(機密不落設定檔, 只寫變數名),
|
|
60
|
+
// 而dispatchAiFallback只認keys陣列——本函數負責envVar → keys之展開,
|
|
61
|
+
// 缺對應環境變數者停用該條目並列入skipped回報(不中斷、不throw),
|
|
62
|
+
// 訂閱登入態條目(claude/codex等無envVar)原樣通過。
|
|
63
|
+
//
|
|
64
|
+
// 【自選】opt.pick給id陣列即可只取用部分條目, 且依pick之順序回傳
|
|
65
|
+
// (順序即dispatchAiFallback之優先序); 查無之id列入missing回報。
|
|
66
|
+
//
|
|
67
|
+
// 【後處理單一入口: opt.exes與opt.patch】消費端常需於展開後對條目做兩類覆寫:
|
|
68
|
+
// ①逐kind注入CLI執行檔絕對路徑(Windows排程於session 0執行時PATH可能不含npm
|
|
69
|
+
// 全域目錄, 靠指令名會ENOENT); ②逐id覆寫任意欄位(如各家實測耗時相差近10倍,
|
|
70
|
+
// timeoutMs須逐條指定)。此前只能於呼叫端自行map, 而陣列版(providers)與表格版
|
|
71
|
+
// (table)若各自後處理, 極易只套用其一——使用端殷鑑(2026-08-14): 逐條timeout
|
|
72
|
+
// 只加在陣列版, 工作流走表格版全部落回全域預設而不自知。後處理收進本函數,
|
|
73
|
+
// 兩種輸出同源產出, 結構性杜絕單邊套用。
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* 展開providers定義條目:envVar → keys,並可依id自選子集
|
|
78
|
+
*
|
|
79
|
+
* 特點:
|
|
80
|
+
* 條目之envVar依env來源(預設process.env)展開為keys陣列(變數值以逗號分隔多把),envVar欄位自輸出移除;
|
|
81
|
+
* 缺對應環境變數(或值為空)之條目停用並列入skipped,不中斷不throw;
|
|
82
|
+
* 無envVar之條目(訂閱登入態CLI)原樣通過;條目已自帶有效keys者以keys為準;
|
|
83
|
+
* opt.pick可依id自選子集並以pick順序回傳(順序即遞補優先序);
|
|
84
|
+
* opt.exes依kind注入CLI執行檔路徑、opt.patch依id淺合併覆寫欄位——皆於展開後施作,
|
|
85
|
+
* providers與table同源產出故必然一致;
|
|
86
|
+
* 輸入陣列與條目皆不被改動(輸出為淺拷貝)
|
|
87
|
+
*
|
|
88
|
+
* @param {Array} providers 輸入providers條目物件陣列(如providers.mjs之預設匯出)
|
|
89
|
+
* @param {Object} [opt={}] 輸入設定物件,預設{}
|
|
90
|
+
* @param {Object} [opt.env=process.env] 輸入金鑰來源物件(變數名 → 逗號分隔之金鑰字串),預設process.env。建議以readEnvFile('./.env')讀成物件傳入,不污染process.env
|
|
91
|
+
* @param {Array} [opt.pick=null] 輸入自選id字串陣列,依此順序回傳對應條目,查無之id列入missing,預設null代表全取(依原順序)
|
|
92
|
+
* @param {Object} [opt.exes=null] 輸入kind對執行檔絕對路徑之物件(如{claude:'C:/.../claude.exe'}),命中kind之條目補上exe欄位(條目已自帶exe者不覆寫——條目層設定優先),預設null代表不注入
|
|
93
|
+
* @param {Object} [opt.patch=null] 輸入id對部分欄位之物件(如{'claude:sonnet':{timeoutMs:360000}}),命中id之條目淺合併覆寫,於exes之後施作故可覆寫exe,預設null代表不覆寫
|
|
94
|
+
* @returns {Object} 回傳物件,內含providers(可直接餵dispatchAiFallback之條目陣列)、table(id對條目之物件,可直接餵dispatchAiWkf)、skipped(缺環境變數而停用之{id,envVar}陣列)、missing(pick查無之id字串陣列)、hints(missing id對最接近可用id之拼寫提示物件,pick查無多半是打錯字,附最接近id供直接定位;僅為相似度最高者非保證正解,無missing時為空物件)
|
|
95
|
+
* @example
|
|
96
|
+
*
|
|
97
|
+
* import resolveProviders from './src/resolveProviders.mjs'
|
|
98
|
+
* import readEnvFile from './src/readEnvFile.mjs'
|
|
99
|
+
* import providersAll from './src/providers.mjs'
|
|
100
|
+
*
|
|
101
|
+
* //金鑰放.env(變數值以逗號分隔多把), 以readEnvFile讀成物件, 不污染process.env
|
|
102
|
+
* let env = readEnvFile('./.env')
|
|
103
|
+
*
|
|
104
|
+
* //全取: envVar展開為keys, 缺環境變數者列入skipped
|
|
105
|
+
* let { providers, table, skipped } = resolveProviders(providersAll, { env })
|
|
106
|
+
* console.log(providers.length, skipped)
|
|
107
|
+
* // => 17 []
|
|
108
|
+
*
|
|
109
|
+
* //pick打錯字時, missing附拼寫提示hints(最接近之可用id)
|
|
110
|
+
* let rm = resolveProviders(providersAll, { env, pick: ['poolside/laguna-s-2.1'] })
|
|
111
|
+
* console.log(rm.missing, rm.hints)
|
|
112
|
+
* // => [ 'poolside/laguna-s-2.1' ] { 'poolside/laguna-s-2.1': 'poolside:laguna-s-2.1' }
|
|
113
|
+
*
|
|
114
|
+
* //自選: 依pick順序回傳(順序即遞補優先序), 可直接餵dispatchAiFallback
|
|
115
|
+
* let r2 = resolveProviders(providersAll, { env, pick: ['agnes:agnes-3.0-flash', 'claude:sonnet'] })
|
|
116
|
+
* console.log(r2.providers.map((p) => p.id))
|
|
117
|
+
* // => [ 'agnes:agnes-3.0-flash', 'claude:sonnet' ]
|
|
118
|
+
*
|
|
119
|
+
* //後處理: exes逐kind注入執行檔、patch逐id覆寫欄位, 陣列與table同步生效
|
|
120
|
+
* let r3 = resolveProviders(providersAll, {
|
|
121
|
+
* env,
|
|
122
|
+
* pick: ['agnes:agnes-3.0-flash', 'claude:sonnet'],
|
|
123
|
+
* exes: { claude: 'C:/Users/x/.local/bin/claude.exe' },
|
|
124
|
+
* patch: { 'claude:sonnet': { timeoutMs: 360000 } },
|
|
125
|
+
* })
|
|
126
|
+
* console.log(r3.table['claude:sonnet'].exe, r3.table['claude:sonnet'].timeoutMs)
|
|
127
|
+
* // => 'C:/Users/x/.local/bin/claude.exe' 360000
|
|
128
|
+
*
|
|
129
|
+
* //table可直接餵dispatchAiWkf之providers定義表
|
|
130
|
+
* //let wkf = dispatchAiWkf({ providers: r2.table, defaults: { timeoutMs: 1200000 } })
|
|
131
|
+
*
|
|
132
|
+
*/
|
|
133
|
+
function resolveProviders(providers, opt = {}) {
|
|
134
|
+
|
|
135
|
+
//env, 無效回退process.env(瀏覽器環境無process則空物件)
|
|
136
|
+
let env = get(opt, 'env', null)
|
|
137
|
+
if (!isobj(env)) {
|
|
138
|
+
env = (typeof process !== 'undefined' && process && isobj(process.env)) ? process.env : {}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
//providersRaw
|
|
142
|
+
let providersRaw = isarr(providers) ? providers.filter(isobj) : []
|
|
143
|
+
|
|
144
|
+
//pick, 依id自選並依pick順序回傳
|
|
145
|
+
let pick = get(opt, 'pick', null)
|
|
146
|
+
let missing = []
|
|
147
|
+
let selected = providersRaw
|
|
148
|
+
if (isearr(pick)) {
|
|
149
|
+
selected = []
|
|
150
|
+
for (let id of pick) {
|
|
151
|
+
let entry = providersRaw.find((p) => get(p, 'id', null) === id)
|
|
152
|
+
if (entry) {
|
|
153
|
+
selected.push(entry)
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
missing.push(String(id))
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
//hints, missing之拼寫提示: 自全部條目id中找最接近者——實務上pick查無多半是打錯字
|
|
162
|
+
//(如'poolside/laguna'誤作分隔符), 附上最接近id可直接定位; 僅為相似度最高者, 非保證正解
|
|
163
|
+
let hints = {}
|
|
164
|
+
if (missing.length > 0) {
|
|
165
|
+
let ids = providersRaw.map((p) => get(p, 'id', null)).filter(isestr)
|
|
166
|
+
for (let mid of missing) {
|
|
167
|
+
hints[mid] = (ids.length > 0) ? get(strFindSimilar(mid, ids), 'bestMatch.target', null) : null
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
//展開envVar → keys
|
|
172
|
+
let out = []
|
|
173
|
+
let skipped = []
|
|
174
|
+
for (let entry of selected) {
|
|
175
|
+
let envVar = get(entry, 'envVar', null)
|
|
176
|
+
|
|
177
|
+
//無envVar(訂閱登入態CLI)或已自帶有效keys, 原樣通過(僅移除envVar欄位)
|
|
178
|
+
if (!isestr(envVar) || isearr(get(entry, 'keys', null))) {
|
|
179
|
+
out.push(omit(entry, ['envVar']))
|
|
180
|
+
continue
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
//envVar → keys, 變數值以逗號分隔多把
|
|
184
|
+
let keys = String(get(env, envVar, '') || '').split(',').map((k) => k.trim()).filter(Boolean)
|
|
185
|
+
if (keys.length === 0) {
|
|
186
|
+
|
|
187
|
+
//缺環境變數: 停用該條目並回報, 不中斷(設計providers原則§四.4)
|
|
188
|
+
skipped.push({ id: get(entry, 'id', ''), envVar })
|
|
189
|
+
continue
|
|
190
|
+
}
|
|
191
|
+
out.push({ ...omit(entry, ['envVar']), keys })
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
//後處理: exes(逐kind)與patch(逐id), 於table組建「之前」施作——
|
|
195
|
+
//providers與table由同一份out產出, 兩種輸出必然一致(檔頭之單邊套用殷鑑)
|
|
196
|
+
let exes = get(opt, 'exes', null)
|
|
197
|
+
let patch = get(opt, 'patch', null)
|
|
198
|
+
if (isobj(exes) || isobj(patch)) {
|
|
199
|
+
out = out.map((entry) => {
|
|
200
|
+
let e = entry
|
|
201
|
+
|
|
202
|
+
//exes: 條目已自帶exe者不覆寫(條目層設定優先於全域注入)
|
|
203
|
+
let exe = isobj(exes) ? get(exes, get(e, 'kind', ''), null) : null
|
|
204
|
+
if (isestr(exe) && !isestr(get(e, 'exe', null))) {
|
|
205
|
+
e = { ...e, exe }
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
//patch: 依id淺合併, 於exes之後施作故可覆寫exe
|
|
209
|
+
let pt = isobj(patch) ? get(patch, get(e, 'id', ''), null) : null
|
|
210
|
+
if (isobj(pt)) {
|
|
211
|
+
e = { ...e, ...pt }
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return e
|
|
215
|
+
})
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
//table, id → 條目, 可直接作dispatchAiWkf之providers定義表
|
|
219
|
+
let table = {}
|
|
220
|
+
for (let entry of out) {
|
|
221
|
+
table[entry.id] = entry
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return { providers: out, table, skipped, missing, hints }
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
export default resolveProviders
|
|
229
229
|
</code></pre>
|
|
230
230
|
</article>
|
|
231
231
|
</section>
|
|
@@ -240,7 +240,7 @@ export default resolveProviders
|
|
|
240
240
|
<br class="clear">
|
|
241
241
|
|
|
242
242
|
<footer>
|
|
243
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
243
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Mon Sep 14 2026 12:59:17 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
244
244
|
</footer>
|
|
245
245
|
|
|
246
246
|
<script>prettyPrint();</script>
|
|
@@ -274,7 +274,7 @@ export { buildChain, NO_SIDE_EFFECT }
|
|
|
274
274
|
<br class="clear">
|
|
275
275
|
|
|
276
276
|
<footer>
|
|
277
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
277
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Mon Sep 14 2026 12:59:17 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
278
278
|
</footer>
|
|
279
279
|
|
|
280
280
|
<script>prettyPrint();</script>
|
|
@@ -162,7 +162,7 @@ export default createFileStore
|
|
|
162
162
|
<br class="clear">
|
|
163
163
|
|
|
164
164
|
<footer>
|
|
165
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
165
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Mon Sep 14 2026 12:59:17 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
166
166
|
</footer>
|
|
167
167
|
|
|
168
168
|
<script>prettyPrint();</script>
|
|
@@ -200,7 +200,7 @@ export default createUsageCounter
|
|
|
200
200
|
<br class="clear">
|
|
201
201
|
|
|
202
202
|
<footer>
|
|
203
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
203
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Mon Sep 14 2026 12:59:17 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
204
204
|
</footer>
|
|
205
205
|
|
|
206
206
|
<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
|
|
170
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Mon Sep 14 2026 12:59:17 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
171
171
|
</footer>
|
|
172
172
|
|
|
173
173
|
<script>prettyPrint();</script>
|
|
@@ -108,7 +108,7 @@ export default NO_SIDE_EFFECT
|
|
|
108
108
|
<br class="clear">
|
|
109
109
|
|
|
110
110
|
<footer>
|
|
111
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
111
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Mon Sep 14 2026 12:59:17 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
112
112
|
</footer>
|
|
113
113
|
|
|
114
114
|
<script>prettyPrint();</script>
|
|
@@ -217,7 +217,7 @@ export { defaultIntegratePrompt }
|
|
|
217
217
|
<br class="clear">
|
|
218
218
|
|
|
219
219
|
<footer>
|
|
220
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
220
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Mon Sep 14 2026 12:59:17 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
221
221
|
</footer>
|
|
222
222
|
|
|
223
223
|
<script>prettyPrint();</script>
|
|
@@ -161,7 +161,7 @@ export default runFanoutPipeline
|
|
|
161
161
|
<br class="clear">
|
|
162
162
|
|
|
163
163
|
<footer>
|
|
164
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
164
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Mon Sep 14 2026 12:59:17 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
165
165
|
</footer>
|
|
166
166
|
|
|
167
167
|
<script>prettyPrint();</script>
|
|
@@ -183,7 +183,7 @@ export default runRolePipeline
|
|
|
183
183
|
<br class="clear">
|
|
184
184
|
|
|
185
185
|
<footer>
|
|
186
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
186
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Mon Sep 14 2026 12:59:17 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
187
187
|
</footer>
|
|
188
188
|
|
|
189
189
|
<script>prettyPrint();</script>
|
|
@@ -154,7 +154,7 @@ export default salvageTruncatedArray
|
|
|
154
154
|
<br class="clear">
|
|
155
155
|
|
|
156
156
|
<footer>
|
|
157
|
-
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on
|
|
157
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Mon Sep 14 2026 12:59:17 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
158
158
|
</footer>
|
|
159
159
|
|
|
160
160
|
<script>prettyPrint();</script>
|
package/package.json
CHANGED
|
@@ -1,22 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "w-dispatch-ai",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.25",
|
|
4
4
|
"main": "dist/w-dispatch-ai.umd.js",
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"wsemi": "^1.8.
|
|
6
|
+
"wsemi": "^1.8.92"
|
|
7
7
|
},
|
|
8
8
|
"devDependencies": {
|
|
9
|
-
"w-package-tools": "^1.1.
|
|
9
|
+
"w-package-tools": "^1.1.16"
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
|
-
"test": "mocha --parallel --timeout
|
|
12
|
+
"test": "mocha --parallel \"test/*.test.mjs\" --timeout 180000",
|
|
13
13
|
"deploy": "gh-pages -d docs"
|
|
14
14
|
},
|
|
15
|
-
"mocha": {
|
|
16
|
-
"spec": [
|
|
17
|
-
"test/unit-*.test.mjs"
|
|
18
|
-
]
|
|
19
|
-
},
|
|
20
15
|
"repository": {
|
|
21
16
|
"type": "git",
|
|
22
17
|
"url": "git+https://github.com/yuda-lyu/w-dispatch-ai.git"
|