w-dispatch-ai 1.0.0

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 (73) hide show
  1. package/.editorconfig +9 -0
  2. package/.eslintignore +3 -0
  3. package/.eslintrc.js +55 -0
  4. package/.jsdoc +25 -0
  5. package/LICENSE +21 -0
  6. package/README.md +207 -0
  7. package/SECURITY.md +5 -0
  8. package/babel.config.js +16 -0
  9. package/dist/w-dispatch-ai.umd.js +7 -0
  10. package/dist/w-dispatch-ai.umd.js.map +1 -0
  11. package/docs/WDispatchAi.mjs.html +110 -0
  12. package/docs/adapters.mjs.html +100 -0
  13. package/docs/dispatchAi.mjs.html +133 -0
  14. package/docs/dispatchClaude.mjs.html +190 -0
  15. package/docs/dispatchCodex.mjs.html +191 -0
  16. package/docs/dispatchOpencode.mjs.html +260 -0
  17. package/docs/fonts/Montserrat/Montserrat-Bold.eot +0 -0
  18. package/docs/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
  19. package/docs/fonts/Montserrat/Montserrat-Bold.woff +0 -0
  20. package/docs/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
  21. package/docs/fonts/Montserrat/Montserrat-Regular.eot +0 -0
  22. package/docs/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
  23. package/docs/fonts/Montserrat/Montserrat-Regular.woff +0 -0
  24. package/docs/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
  25. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
  26. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +978 -0
  27. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
  28. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
  29. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
  30. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
  31. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1049 -0
  32. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
  33. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
  34. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
  35. package/docs/getCliArgs.mjs.html +126 -0
  36. package/docs/getErrorResult.mjs.html +115 -0
  37. package/docs/global.html +2924 -0
  38. package/docs/index.html +84 -0
  39. package/docs/scripts/collapse.js +39 -0
  40. package/docs/scripts/commonNav.js +28 -0
  41. package/docs/scripts/linenumber.js +25 -0
  42. package/docs/scripts/nav.js +12 -0
  43. package/docs/scripts/polyfill.js +4 -0
  44. package/docs/scripts/prettify/Apache-License-2.0.txt +202 -0
  45. package/docs/scripts/prettify/lang-css.js +2 -0
  46. package/docs/scripts/prettify/prettify.js +28 -0
  47. package/docs/scripts/search.js +99 -0
  48. package/docs/styles/jsdoc.css +776 -0
  49. package/docs/styles/prettify.css +80 -0
  50. package/g.mjs +94 -0
  51. package/package.json +38 -0
  52. package/script.txt +17 -0
  53. package/src/WDispatchAi.mjs +38 -0
  54. package/src/adapters.mjs +28 -0
  55. package/src/dispatchAi.mjs +61 -0
  56. package/src/dispatchClaude.mjs +118 -0
  57. package/src/dispatchCodex.mjs +119 -0
  58. package/src/dispatchOpencode.mjs +188 -0
  59. package/src/getCliArgs.mjs +54 -0
  60. package/src/getErrorResult.mjs +43 -0
  61. package/test/tools/fakeCliForTest.mjs +139 -0
  62. package/test/unit-WDispatchAi.test.mjs +79 -0
  63. package/test/unit-adapters.test.mjs +34 -0
  64. package/test/unit-dispatchAi.test.mjs +104 -0
  65. package/test/unit-dispatchClaude.test.mjs +144 -0
  66. package/test/unit-dispatchCodex.test.mjs +113 -0
  67. package/test/unit-dispatchOpencode.test.mjs +176 -0
  68. package/test/unit-getCliArgs.test.mjs +55 -0
  69. package/test/unit-getErrorResult.test.mjs +45 -0
  70. package/toolg/addVersion.mjs +4 -0
  71. package/toolg/cleanFolder.mjs +5 -0
  72. package/toolg/gDistRollup.mjs +24 -0
  73. package/toolg/modifyReadme.mjs +4 -0
@@ -0,0 +1,191 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+
5
+ <meta charset="utf-8">
6
+ <title>dispatchCodex.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#dispatchAi">dispatchAi</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#getCliArgs">getCliArgs</a></li><li><a href="global.html#getErrorResult">getErrorResult</a></li></ul>
33
+
34
+ </nav>
35
+
36
+ <div id="main">
37
+
38
+ <h1 class="page-title">dispatchCodex.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 isestr from 'wsemi/src/isestr.mjs'
51
+ import execCli from 'wsemi/src/execCli.mjs'
52
+ import getCliArgs from './getCliArgs.mjs'
53
+ import getErrorResult from './getErrorResult.mjs'
54
+
55
+
56
+ // dispatchCodex.mjs — 以OpenAI Codex CLI呼叫GPT模型
57
+ //
58
+ // 【調用方式】參考全域技能dispatch-codex之慣例,依專案方針「不直接引用全域技能」,
59
+ // 將其調用方式移植於此,方便本專案自行偵錯、修改與擴充。
60
+ //
61
+ // 【走stdin而非位置參數】技能文件的範例是把prompt當位置參數,但摘要內文可達數萬字,
62
+ // 當命令列參數會spawn ENAMETOOLONG(本專案在opencode上已實際踩過)。
63
+ // 2026-08-08實測:codex exec未帶位置prompt時可從stdin讀取,
64
+ // 以gpt-5.6-luna產出合規JSON摘要(10.5s),與位置參數版結果等價。
65
+ //
66
+ // 【認證】沿用Codex CLI既有登入狀態,不逐次注入API key。
67
+
68
+
69
+ //預設值
70
+ let DEFAULT_EXE = 'codex'
71
+ let DEFAULT_SANDBOX = 'workspace-write'
72
+
73
+
74
+ //本轉接器自用之設定鍵, 其餘鍵一律原樣轉傳execCli
75
+ let OWN_KEYS = ['exe', 'model', 'sandbox', 'extraArgs', 'input']
76
+
77
+
78
+ /**
79
+ * 以OpenAI Codex CLI呼叫GPT模型
80
+ *
81
+ * 特點:
82
+ * prompt一律走stdin而非位置參數,因摘要內文可達數萬字,當命令列參數會spawn ENAMETOOLONG;
83
+ * 固定帶`--skip-git-repo-check`,令非git倉庫之工作目錄亦可執行;
84
+ * 沿用Codex CLI既有登入狀態,無逐次注入API key之概念,故無key參數;
85
+ * 未給model時不帶`-m`旗標,由CLI自行決定使用模型;
86
+ * 本函數不會reject,一律以結果物件之ok與error欄位回報成敗
87
+ *
88
+ * @param {String} prompt 輸入提示詞字串,一律以stdin傳入子進程
89
+ * @param {Object} [opt={}] 輸入設定物件,預設{}
90
+ * @param {String} [opt.exe='codex'] 輸入codex執行檔名稱或絕對路徑字串,給予名稱時由execCli自系統PATH解析,預設'codex'
91
+ * @param {String} [opt.model=''] 輸入模型ID字串,例如'gpt-5.6-luna',預設''代表不帶`-m`旗標
92
+ * @param {String} [opt.sandbox='workspace-write'] 輸入沙箱模式字串,例如'read-only'、'workspace-write'、'danger-full-access',預設'workspace-write'
93
+ * @param {Array} [opt.extraArgs=[]] 輸入額外命令列旗標字串陣列,例如['--config', 'model_reasoning_effort="max"'],將接於固定旗標之後,預設[]
94
+ * @param {Number} [opt.timeoutMs=120000] 輸入逾時毫秒正整數,逾時將強制關閉子進程及其子孫程序,預設120000
95
+ * @param {String} [opt.cwd=process.cwd()] 輸入子進程工作目錄字串,預設process.cwd()
96
+ * @param {String|Function} [opt.validate=undefined] 輸入stdout驗證規則字串或自訂驗證函數,規則字串支援'nonempty'、'json'、'min:100',多規則可用逗號串接,預設undefined代表不驗證
97
+ * @param {Number} [opt.maxRetries=0] 輸入失敗後最大重試次數非負整數,預設0
98
+ * @returns {Promise} 回傳Promise,resolve回傳結果物件,內含ok(是否成功布林值)、stdout(標準輸出字串)、stderr(標準錯誤字串)、code(離開碼)、error(錯誤訊息字串,成功時為空字串)、durationMs(耗時毫秒)、attempts(實際嘗試次數),本函數不會reject
99
+ * @example
100
+ * //need codex cli in system PATH
101
+ *
102
+ * import dispatchCodex from './src/dispatchCodex.mjs'
103
+ *
104
+ * let test = async () => {
105
+ *
106
+ * let r = await dispatchCodex('請只回覆兩個字:完成', { model: 'gpt-5.6-luna', sandbox: 'read-only' })
107
+ * console.log(r.ok, r.stdout.includes('完成'))
108
+ * // => true true
109
+ *
110
+ * let re = await dispatchCodex('abc', { exe: 'codex-not-exist' })
111
+ * console.log(re.ok, re.error.includes('ENOENT'))
112
+ * // => false true
113
+ *
114
+ * }
115
+ * await test()
116
+ * .catch((err) => {
117
+ * console.log(err)
118
+ * })
119
+ *
120
+ */
121
+ async function dispatchCodex(prompt, opt = {}) {
122
+
123
+ //check prompt, 不reject故以錯誤結果物件回報
124
+ if (!isestr(prompt)) {
125
+ return getErrorResult('prompt must be a non-empty string')
126
+ }
127
+
128
+ //exe, 無效回退預設'codex', 由execCli自系統PATH解析實體路徑
129
+ let exe = get(opt, 'exe', null)
130
+ if (!isestr(exe)) {
131
+ exe = DEFAULT_EXE
132
+ }
133
+
134
+ //model, 無效時整段`-m`旗標不出現, 由CLI自行決定使用模型
135
+ let model = get(opt, 'model', null)
136
+
137
+ //sandbox, 無效回退預設'workspace-write'
138
+ let sandbox = get(opt, 'sandbox', null)
139
+ if (!isestr(sandbox)) {
140
+ sandbox = DEFAULT_SANDBOX
141
+ }
142
+
143
+ //extraArgs
144
+ let extraArgs = get(opt, 'extraArgs', null)
145
+
146
+ //args, --skip-git-repo-check令非git倉庫之工作目錄亦可執行, 缺此旗標codex會拒絕執行
147
+ let args = getCliArgs(
148
+ 'exec',
149
+ ['--sandbox', sandbox],
150
+ '--skip-git-repo-check',
151
+ isestr(model) ? ['-m', model] : [],
152
+ extraArgs,
153
+ )
154
+
155
+ //optCli, 剔除本轉接器自用鍵後原樣轉傳, 令呼叫端可用execCli全部設定(例如onStdout、maxBuffer)
156
+ let optCli = omit(opt, OWN_KEYS)
157
+
158
+ //execCli, prompt一律走stdin
159
+ return execCli(exe, args, {
160
+ ...optCli,
161
+ input: prompt,
162
+ })
163
+ }
164
+
165
+
166
+ export default dispatchCodex
167
+ </code></pre>
168
+ </article>
169
+ </section>
170
+
171
+
172
+
173
+
174
+
175
+
176
+ </div>
177
+
178
+ <br class="clear">
179
+
180
+ <footer>
181
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sun Aug 09 2026 22:39:08 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
182
+ </footer>
183
+
184
+ <script>prettyPrint();</script>
185
+ <script src="scripts/polyfill.js"></script>
186
+ <script src="scripts/linenumber.js"></script>
187
+
188
+
189
+
190
+ </body>
191
+ </html>
@@ -0,0 +1,260 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+
5
+ <meta charset="utf-8">
6
+ <title>dispatchOpencode.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#dispatchAi">dispatchAi</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#getCliArgs">getCliArgs</a></li><li><a href="global.html#getErrorResult">getErrorResult</a></li></ul>
33
+
34
+ </nav>
35
+
36
+ <div id="main">
37
+
38
+ <h1 class="page-title">dispatchOpencode.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 isobj from 'wsemi/src/isobj.mjs'
51
+ import isestr from 'wsemi/src/isestr.mjs'
52
+ import execCli from 'wsemi/src/execCli.mjs'
53
+ import getCliArgs from './getCliArgs.mjs'
54
+ import getErrorResult from './getErrorResult.mjs'
55
+
56
+
57
+ // dispatchOpencode.mjs — 以opencode CLI呼叫AI模型
58
+ //
59
+ // 【金鑰注入(2026-08-08於本機實測確認,非讀碼推論)】
60
+ // OPENCODE_AUTH_CONTENT環境變數會「完全覆蓋」opencode的auth.json:
61
+ // 實測帶入無效key → `Error: Invalid API key.`(code=1、訊息在stderr、stdout空);
62
+ // 帶入真實key → 正常回應。以env傳入「不會改寫」auth.json(實測md5前後一致),
63
+ // 屬process層級,可與同時執行的其他專案並行而互不干擾。
64
+ // 註:OPENCODE_API_KEY在auth.json已有憑證時不生效,故一律走OPENCODE_AUTH_CONTENT。
65
+ //
66
+ // 【provider與model必須配對】不同provider的金鑰不可互換:
67
+ // 實測把agnes-ai的金鑰用於opencode/...模型 → `Invalid API key`。
68
+ // 故呼叫端傳入的key/provider/model須為同一組。
69
+ //
70
+ // 【第三方provider須另給config(2026-08-09於本機實測確認)】
71
+ // opencode僅內建自家provider,第三方(例如agnes-ai)未定義於設定檔時,
72
+ // 只注入金鑰仍無法使用:實測`opencode models`不列出該provider之模型,
73
+ // 直接指定模型則回`UnknownError/Unexpected server error`。
74
+ // OPENCODE_CONFIG_CONTENT環境變數可逐次注入設定內容,補上provider定義後
75
+ // `opencode models`即列出agnes-ai/agnes-2.0-flash且可正常對話,
76
+ // 與OPENCODE_AUTH_CONTENT同為process層級,不改寫使用者設定檔。
77
+
78
+
79
+ //預設值
80
+ let DEFAULT_EXE = 'opencode'
81
+ let DEFAULT_AGENT = 'build'
82
+
83
+
84
+ //本轉接器自用之設定鍵, 其餘鍵一律原樣轉傳execCli
85
+ let OWN_KEYS = ['exe', 'model', 'key', 'provider', 'agent', 'config', 'extraArgs', 'input', 'env']
86
+
87
+
88
+ /**
89
+ * 以opencode CLI呼叫AI模型
90
+ *
91
+ * 特點:
92
+ * prompt一律走stdin而非位置參數,因摘要內文可達數萬字,當命令列參數會spawn ENAMETOOLONG,
93
+ * 而opencode run未帶位置message時即從stdin讀取;
94
+ * 同時給予key與provider時,以OPENCODE_AUTH_CONTENT環境變數逐次注入金鑰,
95
+ * 該注入僅作用於當次子進程且不改寫auth.json,故可多把金鑰輪替並與其他程序並行;
96
+ * 未給key或provider時沿用CLI既有登入狀態;
97
+ * 使用opencode未內建之第三方provider時,須另以config給予其provider定義;
98
+ * 本函數不會reject,一律以結果物件之ok與error欄位回報成敗
99
+ *
100
+ * @param {String} prompt 輸入提示詞字串,一律以stdin傳入子進程
101
+ * @param {Object} [opt={}] 輸入設定物件,預設{}
102
+ * @param {String} [opt.exe='opencode'] 輸入opencode執行檔名稱或絕對路徑字串,給予名稱時由execCli自系統PATH解析,預設'opencode'
103
+ * @param {String} [opt.model=''] 輸入模型ID字串,例如'opencode/deepseek-v4-flash-free',預設''代表不帶`-m`旗標
104
+ * @param {String} [opt.key=''] 輸入該provider之API key字串,須與provider同時給予才會注入,預設''代表沿用CLI既有登入狀態
105
+ * @param {String} [opt.provider=''] 輸入key所屬provider名稱字串,須與key同時給予才會注入,且須與model為同一組,預設''
106
+ * @param {Object|String} [opt.config=null] 輸入opencode設定內容物件或其JSON字串,將以OPENCODE_CONFIG_CONTENT逐次注入,供補上第三方provider之定義,預設null代表沿用使用者既有設定檔
107
+ * @param {String} [opt.agent='build'] 輸入opencode代理名稱字串,預設'build'
108
+ * @param {Array} [opt.extraArgs=[]] 輸入額外命令列旗標字串陣列,將接於固定旗標之後,預設[]
109
+ * @param {Object} [opt.env=undefined] 輸入本次調用額外注入之環境變數物件,同時給予key與provider時會再併入OPENCODE_AUTH_CONTENT,預設undefined
110
+ * @param {Number} [opt.timeoutMs=120000] 輸入逾時毫秒正整數,逾時將強制關閉子進程及其子孫程序,預設120000
111
+ * @param {String} [opt.cwd=process.cwd()] 輸入子進程工作目錄字串,預設process.cwd()
112
+ * @param {String|Function} [opt.validate=undefined] 輸入stdout驗證規則字串或自訂驗證函數,規則字串支援'nonempty'、'json'、'min:100',多規則可用逗號串接,預設undefined代表不驗證
113
+ * @param {Number} [opt.maxRetries=0] 輸入失敗後最大重試次數非負整數,預設0
114
+ * @returns {Promise} 回傳Promise,resolve回傳結果物件,內含ok(是否成功布林值)、stdout(標準輸出字串)、stderr(標準錯誤字串)、code(離開碼)、error(錯誤訊息字串,成功時為空字串)、durationMs(耗時毫秒)、attempts(實際嘗試次數),本函數不會reject
115
+ * @example
116
+ * //need opencode cli in system PATH
117
+ *
118
+ * import dispatchOpencode from './src/dispatchOpencode.mjs'
119
+ *
120
+ * let test = async () => {
121
+ *
122
+ * //沿用CLI既有登入狀態
123
+ * let r1 = await dispatchOpencode('請只回覆兩個字:完成', { model: 'opencode/deepseek-v4-flash-free' })
124
+ * console.log(r1.ok, r1.stdout.includes('完成'))
125
+ * // => true true
126
+ *
127
+ * //逐次注入金鑰, key與provider與model須為同一組
128
+ * let r2 = await dispatchOpencode('請只回覆兩個字:完成', {
129
+ * model: 'opencode/deepseek-v4-flash-free',
130
+ * provider: 'opencode',
131
+ * key: 'sk-xxxxxx',
132
+ * })
133
+ * console.log(r2.ok)
134
+ * // => true
135
+ *
136
+ * //opencode未內建之第三方provider, 須另以config給予其定義
137
+ * let r3 = await dispatchOpencode('請只回覆兩個字:完成', {
138
+ * model: 'agnes-ai/agnes-2.0-flash',
139
+ * provider: 'agnes-ai',
140
+ * key: 'sk-xxxxxx',
141
+ * config: {
142
+ * provider: {
143
+ * 'agnes-ai': {
144
+ * npm: '@ai-sdk/openai-compatible',
145
+ * name: 'Agnes',
146
+ * options: { baseURL: 'https://apihub.agnes-ai.com/v1' },
147
+ * models: { 'agnes-2.0-flash': { name: 'Agnes 2.0 Flash' } },
148
+ * },
149
+ * },
150
+ * },
151
+ * })
152
+ * console.log(r3.ok)
153
+ * // => true
154
+ *
155
+ * }
156
+ * await test()
157
+ * .catch((err) => {
158
+ * console.log(err)
159
+ * })
160
+ *
161
+ */
162
+ async function dispatchOpencode(prompt, opt = {}) {
163
+
164
+ //check prompt, 不reject故以錯誤結果物件回報
165
+ if (!isestr(prompt)) {
166
+ return getErrorResult('prompt must be a non-empty string')
167
+ }
168
+
169
+ //exe, 無效回退預設'opencode', 由execCli自系統PATH解析實體路徑
170
+ let exe = get(opt, 'exe', null)
171
+ if (!isestr(exe)) {
172
+ exe = DEFAULT_EXE
173
+ }
174
+
175
+ //model, 無效時整段`-m`旗標不出現, 由CLI自行決定使用模型
176
+ let model = get(opt, 'model', null)
177
+
178
+ //agent, 無效回退預設'build'
179
+ let agent = get(opt, 'agent', null)
180
+ if (!isestr(agent)) {
181
+ agent = DEFAULT_AGENT
182
+ }
183
+
184
+ //extraArgs
185
+ let extraArgs = get(opt, 'extraArgs', null)
186
+
187
+ //args
188
+ let args = getCliArgs(
189
+ 'run',
190
+ ['--agent', agent],
191
+ isestr(model) ? ['-m', model] : [],
192
+ extraArgs,
193
+ )
194
+
195
+ //env, 無效回退undefined代表不覆寫任何變數
196
+ let env = get(opt, 'env', null)
197
+ if (!isobj(env)) {
198
+ env = undefined
199
+ }
200
+
201
+ //config有效才注入, 否則沿用使用者既有設定檔, 物件則序列化為JSON字串
202
+ let config = get(opt, 'config', null)
203
+ if (isobj(config)) {
204
+ config = JSON.stringify(config)
205
+ }
206
+ if (isestr(config)) {
207
+ env = {
208
+ ...env,
209
+ OPENCODE_CONFIG_CONTENT: config,
210
+ }
211
+ }
212
+
213
+ //key與provider皆有效才注入, 否則沿用auth.json既有登入狀態(單金鑰時即為原有行為)
214
+ let key = get(opt, 'key', null)
215
+ let provider = get(opt, 'provider', null)
216
+ if (isestr(key) &amp;&amp; isestr(provider)) {
217
+ env = {
218
+ ...env,
219
+ OPENCODE_AUTH_CONTENT: JSON.stringify({ [provider]: { type: 'api', key } }),
220
+ }
221
+ }
222
+
223
+ //optCli, 剔除本轉接器自用鍵後原樣轉傳, 令呼叫端可用execCli全部設定(例如onStdout、maxBuffer)
224
+ let optCli = omit(opt, OWN_KEYS)
225
+
226
+ //execCli, prompt一律走stdin
227
+ return execCli(exe, args, {
228
+ ...optCli,
229
+ input: prompt,
230
+ env,
231
+ })
232
+ }
233
+
234
+
235
+ export default dispatchOpencode
236
+ </code></pre>
237
+ </article>
238
+ </section>
239
+
240
+
241
+
242
+
243
+
244
+
245
+ </div>
246
+
247
+ <br class="clear">
248
+
249
+ <footer>
250
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.5</a> on Sun Aug 09 2026 22:39:08 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
251
+ </footer>
252
+
253
+ <script>prettyPrint();</script>
254
+ <script src="scripts/polyfill.js"></script>
255
+ <script src="scripts/linenumber.js"></script>
256
+
257
+
258
+
259
+ </body>
260
+ </html>