w-dispatch-ai 1.0.1 → 1.0.3

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.
Files changed (46) hide show
  1. package/README.md +83 -5
  2. package/dist/w-dispatch-ai.umd.js +2 -2
  3. package/dist/w-dispatch-ai.umd.js.map +1 -1
  4. package/docs/WDispatchAi.mjs.html +10 -4
  5. package/docs/adapters.mjs.html +10 -6
  6. package/docs/dispatchAi.mjs.html +2 -2
  7. package/docs/dispatchAiFallback.mjs.html +2 -2
  8. package/docs/dispatchAiWkf.mjs.html +172 -0
  9. package/docs/dispatchAntigravity.mjs.html +264 -0
  10. package/docs/dispatchApiOpenaiCompat.mjs.html +483 -0
  11. package/docs/dispatchClaude.mjs.html +2 -2
  12. package/docs/dispatchCodex.mjs.html +2 -2
  13. package/docs/dispatchOpencode.mjs.html +2 -2
  14. package/docs/getCliArgs.mjs.html +2 -2
  15. package/docs/getErrorResult.mjs.html +2 -2
  16. package/docs/global.html +6095 -1092
  17. package/docs/index.html +2 -2
  18. package/docs/wkf_callAiWithFallback.mjs.html +281 -0
  19. package/docs/wkf_extractJsonLoose.mjs.html +180 -0
  20. package/docs/wkf_runFanout.mjs.html +227 -0
  21. package/docs/wkf_runFanoutPipeline.mjs.html +178 -0
  22. package/docs/wkf_runRolePipeline.mjs.html +195 -0
  23. package/g.mjs +19 -2
  24. package/package.json +1 -1
  25. package/src/WDispatchAi.mjs +8 -2
  26. package/src/adapters.mjs +8 -4
  27. package/src/dispatchAiWkf.mjs +100 -0
  28. package/src/dispatchAntigravity.mjs +192 -0
  29. package/src/dispatchApiOpenaiCompat.mjs +411 -0
  30. package/src/wkf/callAiWithFallback.mjs +209 -0
  31. package/src/wkf/extractJsonLoose.mjs +108 -0
  32. package/src/wkf/runFanout.mjs +155 -0
  33. package/src/wkf/runFanoutPipeline.mjs +106 -0
  34. package/src/wkf/runRolePipeline.mjs +123 -0
  35. package/test/tools/fakeServerForApiTest.mjs +137 -0
  36. package/test/unit-WDispatchAi.test.mjs +17 -6
  37. package/test/unit-adapters.test.mjs +7 -3
  38. package/test/unit-callAiWithFallback.test.mjs +146 -0
  39. package/test/unit-dispatchAi.test.mjs +7 -3
  40. package/test/unit-dispatchAiWkf.test.mjs +118 -0
  41. package/test/unit-dispatchAntigravity.test.mjs +173 -0
  42. package/test/unit-dispatchApiOpenaiCompat.test.mjs +233 -0
  43. package/test/unit-extractJsonLoose.test.mjs +78 -0
  44. package/test/unit-runFanout.test.mjs +166 -0
  45. package/test/unit-runFanoutPipeline.test.mjs +86 -0
  46. package/test/unit-runRolePipeline.test.mjs +163 -0
@@ -0,0 +1,172 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+
5
+ <meta charset="utf-8">
6
+ <title>dispatchAiWkf.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#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>
33
+
34
+ </nav>
35
+
36
+ <div id="main">
37
+
38
+ <h1 class="page-title">dispatchAiWkf.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 isobj from 'wsemi/src/isobj.mjs'
50
+ import callAiWithFallback from './wkf/callAiWithFallback.mjs'
51
+ import runFanout from './wkf/runFanout.mjs'
52
+ import runRolePipeline from './wkf/runRolePipeline.mjs'
53
+ import runFanoutPipeline from './wkf/runFanoutPipeline.mjs'
54
+
55
+
56
+ // dispatchAiWkf.mjs — 工作流工廠: 注入provider定義表與共用預設, 回傳綁定版API
57
+ //
58
+ // 【用途】專案端只需注入一次providers(名稱 → dispatchAiFallback條目)與共用設定
59
+ // (cwd、store、onEvent、timeoutMs…), 之後以名稱宣告工作流即可, 不必每次傳定義表。
60
+ //
61
+ // 【並行與游標之說明】多名額並行且共用同一store時, 游標read-modify-write
62
+ // 可能交錯, 造成金鑰輪替不完全均攤——只影響公平性、不影響正確性(每把金鑰仍有效),
63
+ // 故不加鎖; 要求嚴格均攤者可注入自帶佇列的store。
64
+ //
65
+ // 【本函數為同步工廠會throw】providers無效屬設定錯誤, 應於啟動期即失敗(fail fast),
66
+ // 與各dispatch函數「不reject」之約定不衝突——後者是執行期呼叫, 前者是組裝期設定。
67
+
68
+
69
+ /**
70
+ * 建立AI工作流執行環境(工廠),注入provider定義表與共用預設後回傳綁定版API
71
+ *
72
+ * 特點:
73
+ * providers為名稱對dispatchAiFallback條目之定義表,之後各工作流以名稱宣告主模型與遞補鏈;
74
+ * defaults為共用呼叫設定,各工作流之callOpt與名額規格可逐項覆寫;
75
+ * 回傳之各函數皆不reject;本工廠為同步函數,providers無效時throw(設定錯誤應於啟動期即失敗)
76
+ *
77
+ * @param {Object} opt 輸入設定物件
78
+ * @param {Object} opt.providers 輸入provider定義表物件(名稱 → dispatchAiFallback條目:{ kind, model, keys, exe, provider, config, sandbox, extraArgs... })
79
+ * @param {Object} [opt.defaults={}] 輸入共用呼叫設定物件(cwd、store、onEvent、timeoutMs、budgetMs、maxRetries、promptPrefix、parse等),預設{}
80
+ * @returns {Object} 回傳綁定版API物件,內含callAi(單一名額呼叫)、runFanout(多開+整合)、runRolePipeline(串行角色鏈)、runFanoutPipeline(多開+整合+角色鏈)、providers(定義表原樣)
81
+ * @example
82
+ * //need cli in system PATH
83
+ *
84
+ * import dispatchAiWkf from './src/dispatchAiWkf.mjs'
85
+ *
86
+ * let wkf = dispatchAiWkf({
87
+ * providers: {
88
+ * 'deepseek': { kind: 'opencode', model: 'opencode/deepseek-v4-flash-free', provider: 'opencode', keys: ['sk-xxx'] },
89
+ * 'sonnet': { kind: 'claude', model: 'sonnet' },
90
+ * 'luna': { kind: 'codex', model: 'gpt-5.6-luna' },
91
+ * },
92
+ * defaults: { timeoutMs: 300000 },
93
+ * })
94
+ *
95
+ * let test = async () => {
96
+ *
97
+ * //單一名額: 主模型+遞補鏈
98
+ * let r1 = await wkf.callAi('只回覆JSON: {"a":1}', { spec: { use: 'deepseek', fallback: ['sonnet'] }, check: (j) => j.a === 1 })
99
+ * console.log(r1.ok, r1.json)
100
+ * // => true { a: 1 }
101
+ *
102
+ * //Fanout工作流: 多開執行+單點整合
103
+ * let r2 = await wkf.runFanout({
104
+ * task: '分析並只回覆JSON: {"essence":"..."}',
105
+ * agents: [{ use: 'deepseek', fallback: ['sonnet'] }, { use: 'sonnet' }],
106
+ * integrate: { use: 'luna' },
107
+ * check: (j) => !!j.essence,
108
+ * })
109
+ * console.log(r2.ok, r2.integrated)
110
+ * // => true true
111
+ *
112
+ * }
113
+ * await test()
114
+ * .catch((err) => {
115
+ * console.log(err)
116
+ * })
117
+ *
118
+ */
119
+ function dispatchAiWkf(opt = {}) {
120
+ let providers = get(opt, 'providers', null)
121
+ if (!isobj(providers)) {
122
+ throw new Error('dispatchAiWkf: opt.providers must be an object (name → provider entry)')
123
+ }
124
+ let defaults = get(opt, 'defaults', null)
125
+ if (!isobj(defaults)) {
126
+ defaults = {}
127
+ }
128
+
129
+ return {
130
+ providers,
131
+
132
+ //單一名額呼叫: callAi(prompt, { spec:{use,fallback}, check, ... })
133
+ callAi: (prompt, o = {}) => callAiWithFallback(prompt, { ...defaults, ...o, providers }),
134
+
135
+ //Fanout工作流: runFanout({ task, agents, integrate, check, schema, minCandidates, callOpt? })
136
+ runFanout: (o = {}) => runFanout({ ...o, providers, callOpt: { ...defaults, ...get(o, 'callOpt', {}) } }),
137
+
138
+ //RolePipeline工作流: runRolePipeline({ input, stages, callOpt? })
139
+ runRolePipeline: (o = {}) => runRolePipeline({ ...o, providers, callOpt: { ...defaults, ...get(o, 'callOpt', {}) } }),
140
+
141
+ //FanoutPipeline工作流: runFanoutPipeline({ task, agents, integrate, stages, check, schema, callOpt? })
142
+ runFanoutPipeline: (o = {}) => runFanoutPipeline({ ...o, providers, callOpt: { ...defaults, ...get(o, 'callOpt', {}) } }),
143
+ }
144
+ }
145
+
146
+
147
+ export default dispatchAiWkf
148
+ </code></pre>
149
+ </article>
150
+ </section>
151
+
152
+
153
+
154
+
155
+
156
+
157
+ </div>
158
+
159
+ <br class="clear">
160
+
161
+ <footer>
162
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Tue Aug 11 2026 13:18:34 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
163
+ </footer>
164
+
165
+ <script>prettyPrint();</script>
166
+ <script src="scripts/polyfill.js"></script>
167
+ <script src="scripts/linenumber.js"></script>
168
+
169
+
170
+
171
+ </body>
172
+ </html>
@@ -0,0 +1,264 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+
5
+ <meta charset="utf-8">
6
+ <title>dispatchAntigravity.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#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>
33
+
34
+ </nav>
35
+
36
+ <div id="main">
37
+
38
+ <h1 class="page-title">dispatchAntigravity.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 isbol from 'wsemi/src/isbol.mjs'
52
+ import isestr from 'wsemi/src/isestr.mjs'
53
+ import ispint from 'wsemi/src/ispint.mjs'
54
+ import cint from 'wsemi/src/cint.mjs'
55
+ import execCli from 'wsemi/src/execCli.mjs'
56
+ import getCliArgs from './getCliArgs.mjs'
57
+ import getErrorResult from './getErrorResult.mjs'
58
+
59
+
60
+ // dispatchAntigravity.mjs — 以Google Antigravity CLI(agy)呼叫AI模型
61
+ //
62
+ // agy為Google官方之Gemini CLI後繼者(Gemini CLI已於2026-06-18停服), 命令名為agy非antigravity。
63
+ // 實測其models清單除Gemini系外亦含claude與gpt-oss等模型, 屬多模型閘道。
64
+ //
65
+ // 【prompt走--print旗標, 不走stdin(2026-08-10於本機agy 1.1.11實測確認)】
66
+ // --print為帶值旗標(無值即回`flag needs an argument: -print`), 不可能由stdin取prompt;
67
+ // 把prompt塞stdin而args無--print會進互動模式卡住。此為與另三家轉接器最大差異。
68
+ //
69
+ // 【命令列長度上限(實測)】prompt作為命令列參數受Windows CreateProcess之32767字元上限:
70
+ // 純文字32600可spawn、32700即spawn ENAMETOOLONG(同步拋出, 會穿透execCli成rejection)。
71
+ // 且含引號之prompt經spawn轉義後長度會膨脹(實測2萬個引號轉義後仍炸), 故防護須兩層:
72
+ // 前置長度檢查(常見情境給清楚錯誤訊息) + try/catch兜底(轉義膨脹等漏網情境),
73
+ // 兩層皆回錯誤結果物件, 維持本套件「不reject」之契約。
74
+ //
75
+ // 【model與effort之衝突規則(實測)】帶檔位之slug(如gemini-3.1-pro-high)與--effort同時給定時,
76
+ // 檔位「不一致」才拒絕(`--model gemini-3.1-pro-high conflicts with --effort=low`, exit 1),
77
+ // 一致(gemini-3.1-pro-high + --effort high)則放行; 基礎slug(如gemini-3.1-pro)搭配effort亦放行。
78
+ // 本轉接器不預判slug格式(模型清單會演進), 衝突時由agy回報conflicts錯誤。
79
+ //
80
+ // 【雙逾時對齊】agy自身有--print-timeout(預設5m0s), 與execCli之timeoutMs為兩層獨立逾時。
81
+ // printTimeout未給時由timeoutMs推導並預留30秒緩衝, 令CLI先於外層逾時,
82
+ // 使錯誤訊息來自agy自身而非被外層強殺。
83
+
84
+
85
+ //預設值
86
+ let DEFAULT_EXE = 'agy'
87
+ let DEFAULT_TIMEOUT_MS = 300000 //agent型CLI, 對齊agy自身print-timeout預設5m0s, 不沿用套件通用120000
88
+ let MAX_PROMPT_LENGTH = 30000 //命令列上限32767扣除exe路徑與旗標後之保守值
89
+ let PRINT_TIMEOUT_BUFFER_S = 30
90
+ let MIN_PRINT_TIMEOUT_S = 30
91
+
92
+
93
+ //本轉接器自用之設定鍵, 其餘鍵一律原樣轉傳execCli
94
+ let OWN_KEYS = ['exe', 'model', 'effort', 'skipPermissions', 'printTimeout', 'addDirs', 'extraArgs', 'input']
95
+
96
+
97
+ /**
98
+ * 以Google Antigravity CLI(agy)呼叫AI模型
99
+ *
100
+ * 特點:
101
+ * prompt作為`--print`旗標之值傳遞而非stdin(agy介面如此,塞stdin會進互動模式卡住),
102
+ * 故prompt受命令列長度上限約束,超過30000字元回傳錯誤結果物件;
103
+ * model須為`agy models`第一欄之slug(如gemini-3.6-flash-low),注意agy錯誤訊息列出的是顯示名稱而非slug;
104
+ * 帶檔位之slug(-high/-medium/-low結尾)與effort同時給定且檔位不一致時agy回conflicts錯誤(一致則放行),
105
+ * effort需agy>=1.1.11,建議搭配不帶檔位之基礎slug(如gemini-3.1-pro)使用;
106
+ * 預設帶`--dangerously-skip-permissions`令非互動print模式不卡權限確認,可給予skipPermissions為false保留權限閘門;
107
+ * agy自身之--print-timeout未給時由timeoutMs推導並預留30秒緩衝,令CLI先於外層逾時;
108
+ * 沿用agy既有OAuth登入狀態(首次須於桌面互動模式完成登入);
109
+ * 本函數不會reject,一律以結果物件之ok與error欄位回報成敗
110
+ *
111
+ * @param {String} prompt 輸入提示詞字串,作為`--print`旗標之值傳遞,長度上限30000字元
112
+ * @param {Object} [opt={}] 輸入設定物件,預設{}
113
+ * @param {String} [opt.exe='agy'] 輸入agy執行檔名稱或絕對路徑字串,命令名為agy非antigravity,給予名稱時由execCli自系統PATH解析,預設'agy'
114
+ * @param {String} [opt.model=''] 輸入模型slug字串,須為`agy models`第一欄之slug,例如'gemini-3.6-flash-low'、'gemini-3.1-pro-high',預設''代表不帶`--model`旗標由agy自行決定
115
+ * @param {String} [opt.effort=''] 輸入推理深度字串,可選'low'、'medium'、'high',需agy>=1.1.11,建議搭配不帶檔位之基礎slug;與帶檔位slug併用且檔位不一致時agy回conflicts錯誤,預設''代表不帶
116
+ * @param {Boolean} [opt.skipPermissions=true] 輸入是否帶`--dangerously-skip-permissions`旗標布林值,false代表保留CLI權限閘門,預設true
117
+ * @param {String} [opt.printTimeout=''] 輸入agy自身等待上限字串(如'10m'、'570s'),預設''代表由timeoutMs推導(扣30秒緩衝,下限30秒)
118
+ * @param {Array} [opt.addDirs=[]] 輸入加入workspace之目錄字串陣列,逐項展開為`--add-dir`,預設[]
119
+ * @param {Array} [opt.extraArgs=[]] 輸入額外命令列旗標字串陣列(如--output-format、--json-schema、--mode),將接於固定旗標之後、`--print`之前,預設[]
120
+ * @param {Number} [opt.timeoutMs=300000] 輸入逾時毫秒正整數,逾時將強制關閉子進程及其子孫程序,agy為agent型CLI故預設較長之300000,預設300000
121
+ * @param {String} [opt.cwd=process.cwd()] 輸入子進程工作目錄字串,預設process.cwd()
122
+ * @param {String|Function} [opt.validate=undefined] 輸入stdout驗證規則字串或自訂驗證函數,規則字串支援'nonempty'、'json'、'min:100',多規則可用逗號串接,預設undefined代表不驗證
123
+ * @param {Number} [opt.maxRetries=0] 輸入失敗後最大重試次數非負整數,預設0
124
+ * @returns {Promise} 回傳Promise,resolve回傳結果物件,內含ok(是否成功布林值)、stdout(標準輸出字串)、stderr(標準錯誤字串)、code(離開碼)、error(錯誤訊息字串,成功時為空字串)、durationMs(耗時毫秒)、attempts(實際嘗試次數),本函數不會reject
125
+ * @example
126
+ * //need agy cli in system PATH, and OAuth login completed
127
+ *
128
+ * import dispatchAntigravity from './src/dispatchAntigravity.mjs'
129
+ *
130
+ * let test = async () => {
131
+ *
132
+ * let r = await dispatchAntigravity('請只回覆兩個字:完成', { model: 'gemini-3.6-flash-low' })
133
+ * console.log(r.ok, r.stdout.trim())
134
+ * // => true 完成
135
+ *
136
+ * //基礎slug搭配effort(不可用帶檔位之slug併用effort)
137
+ * let r2 = await dispatchAntigravity('請只回覆兩個字:完成', { model: 'gemini-3.1-pro', effort: 'low' })
138
+ * console.log(r2.ok)
139
+ * // => true
140
+ *
141
+ * let re = await dispatchAntigravity('')
142
+ * console.log(re.ok, re.error)
143
+ * // => false 'prompt must be a non-empty string'
144
+ *
145
+ * }
146
+ * await test()
147
+ * .catch((err) => {
148
+ * console.log(err)
149
+ * })
150
+ *
151
+ */
152
+ async function dispatchAntigravity(prompt, opt = {}) {
153
+
154
+ //check prompt, 不reject故以錯誤結果物件回報
155
+ if (!isestr(prompt)) {
156
+ return getErrorResult('prompt must be a non-empty string')
157
+ }
158
+
159
+ //check prompt length, agy之prompt走命令列旗標而非stdin, 受CreateProcess 32767字元上限約束
160
+ if (prompt.length > MAX_PROMPT_LENGTH) {
161
+ return getErrorResult(`prompt too long (${prompt.length} chars > ${MAX_PROMPT_LENGTH}), agy passes prompt via --print flag and Windows command line is capped at 32767 chars`)
162
+ }
163
+
164
+ //exe, 無效回退預設'agy', 由execCli自系統PATH解析實體路徑
165
+ let exe = get(opt, 'exe', null)
166
+ if (!isestr(exe)) {
167
+ exe = DEFAULT_EXE
168
+ }
169
+
170
+ //model, 無效時整段`--model`旗標不出現, 由agy自行決定使用模型
171
+ let model = get(opt, 'model', null)
172
+
173
+ //effort, 無效時整段`--effort`旗標不出現; 與帶檔位slug之衝突由agy判定(檔位不一致時conflicts錯誤, exit 1)
174
+ let effort = get(opt, 'effort', null)
175
+
176
+ //skipPermissions, 非布林值回退預設true(非互動print模式不卡權限確認)
177
+ let skipPermissions = get(opt, 'skipPermissions', null)
178
+ if (!isbol(skipPermissions)) {
179
+ skipPermissions = true
180
+ }
181
+
182
+ //timeoutMs, 先行取值以供printTimeout推導, agy專屬預設300000
183
+ let timeoutMs = get(opt, 'timeoutMs', null)
184
+ if (!ispint(timeoutMs)) {
185
+ timeoutMs = DEFAULT_TIMEOUT_MS
186
+ }
187
+ else {
188
+ timeoutMs = cint(timeoutMs)
189
+ }
190
+
191
+ //printTimeout, 未給時由timeoutMs推導並預留緩衝, 令agy先於外層逾時而回報自身錯誤訊息
192
+ let printTimeout = get(opt, 'printTimeout', null)
193
+ if (!isestr(printTimeout)) {
194
+ printTimeout = `${Math.max(MIN_PRINT_TIMEOUT_S, Math.floor(timeoutMs / 1000) - PRINT_TIMEOUT_BUFFER_S)}s`
195
+ }
196
+
197
+ //addDirs, 逐項展開為--add-dir(agy該旗標可重複)
198
+ let addDirs = get(opt, 'addDirs', null)
199
+ let addDirArgs = []
200
+ if (isarr(addDirs)) {
201
+ for (let d of addDirs) {
202
+ if (isestr(d)) {
203
+ addDirArgs.push('--add-dir', d)
204
+ }
205
+ }
206
+ }
207
+
208
+ //extraArgs
209
+ let extraArgs = get(opt, 'extraArgs', null)
210
+
211
+ //args, prompt作為--print之值放最後
212
+ let args = getCliArgs(
213
+ skipPermissions ? '--dangerously-skip-permissions' : [],
214
+ ['--print-timeout', printTimeout],
215
+ isestr(model) ? ['--model', model] : [],
216
+ isestr(effort) ? ['--effort', effort] : [],
217
+ addDirArgs,
218
+ extraArgs,
219
+ ['--print', prompt],
220
+ )
221
+
222
+ //optCli, 剔除本轉接器自用鍵後原樣轉傳, 令呼叫端可用execCli全部設定(例如onStdout、maxBuffer)
223
+ let optCli = omit(opt, OWN_KEYS)
224
+
225
+ //execCli, 不帶input(agy由--print取得prompt); try/catch兜底轉義膨脹等
226
+ //前置檢查漏網之spawn同步拋出(如ENAMETOOLONG), 維持不reject契約
227
+ try {
228
+ return await execCli(exe, args, {
229
+ ...optCli,
230
+ timeoutMs,
231
+ })
232
+ }
233
+ catch (err) {
234
+ return getErrorResult(`${err.code || 'UNKNOWN'}: ${err.message}`)
235
+ }
236
+ }
237
+
238
+
239
+ export default dispatchAntigravity
240
+ </code></pre>
241
+ </article>
242
+ </section>
243
+
244
+
245
+
246
+
247
+
248
+
249
+ </div>
250
+
251
+ <br class="clear">
252
+
253
+ <footer>
254
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Tue Aug 11 2026 13:18:34 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
255
+ </footer>
256
+
257
+ <script>prettyPrint();</script>
258
+ <script src="scripts/polyfill.js"></script>
259
+ <script src="scripts/linenumber.js"></script>
260
+
261
+
262
+
263
+ </body>
264
+ </html>