@huyuan-ai/cli 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 (55) hide show
  1. package/README.md +99 -0
  2. package/dist/cli/program.d.ts +3 -0
  3. package/dist/cli/program.d.ts.map +1 -0
  4. package/dist/cli/program.js +19 -0
  5. package/dist/cli/program.js.map +1 -0
  6. package/dist/commands/install.d.ts +2 -0
  7. package/dist/commands/install.d.ts.map +1 -0
  8. package/dist/commands/install.js +75 -0
  9. package/dist/commands/install.js.map +1 -0
  10. package/dist/constants.d.ts +9 -0
  11. package/dist/constants.d.ts.map +1 -0
  12. package/dist/constants.js +29 -0
  13. package/dist/constants.js.map +1 -0
  14. package/dist/core/install.d.ts +4 -0
  15. package/dist/core/install.d.ts.map +1 -0
  16. package/dist/core/install.js +89 -0
  17. package/dist/core/install.js.map +1 -0
  18. package/dist/core/login.d.ts +3 -0
  19. package/dist/core/login.d.ts.map +1 -0
  20. package/dist/core/login.js +11 -0
  21. package/dist/core/login.js.map +1 -0
  22. package/dist/index.d.ts +3 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +13 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/integrations/opencli/bootstrap.d.ts +8 -0
  27. package/dist/integrations/opencli/bootstrap.d.ts.map +1 -0
  28. package/dist/integrations/opencli/bootstrap.js +20 -0
  29. package/dist/integrations/opencli/bootstrap.js.map +1 -0
  30. package/dist/integrations/opencli/commands/doubao-ask-with-citations.d.ts +10 -0
  31. package/dist/integrations/opencli/commands/doubao-ask-with-citations.d.ts.map +1 -0
  32. package/dist/integrations/opencli/commands/doubao-ask-with-citations.js +323 -0
  33. package/dist/integrations/opencli/commands/doubao-ask-with-citations.js.map +1 -0
  34. package/dist/integrations/opencli/execute-registry-command.d.ts +11 -0
  35. package/dist/integrations/opencli/execute-registry-command.d.ts.map +1 -0
  36. package/dist/integrations/opencli/execute-registry-command.js +45 -0
  37. package/dist/integrations/opencli/execute-registry-command.js.map +1 -0
  38. package/dist/sites/doubao/ask-with-citations.d.ts +14 -0
  39. package/dist/sites/doubao/ask-with-citations.d.ts.map +1 -0
  40. package/dist/sites/doubao/ask-with-citations.js +21 -0
  41. package/dist/sites/doubao/ask-with-citations.js.map +1 -0
  42. package/dist/sites/doubao/ask.d.ts +11 -0
  43. package/dist/sites/doubao/ask.d.ts.map +1 -0
  44. package/dist/sites/doubao/ask.js +18 -0
  45. package/dist/sites/doubao/ask.js.map +1 -0
  46. package/dist/sites/doubao/register.d.ts +4 -0
  47. package/dist/sites/doubao/register.d.ts.map +1 -0
  48. package/dist/sites/doubao/register.js +30 -0
  49. package/dist/sites/doubao/register.js.map +1 -0
  50. package/dist/utils/config.d.ts +23 -0
  51. package/dist/utils/config.d.ts.map +1 -0
  52. package/dist/utils/config.js +41 -0
  53. package/dist/utils/config.js.map +1 -0
  54. package/package.json +40 -0
  55. package/vendor/opencli/README.md +288 -0
@@ -0,0 +1,323 @@
1
+ /**
2
+ * 注册 `doubao/ask-with-citations`:在 `bootstrapOpencli` 的 discoverClis 之后执行,
3
+ * 与内置 `doubao/ask` 并列,不修改 vendor/opencli 源码。
4
+ */
5
+ import { DOUBAO_DOMAIN, sendDoubaoMessage } from '../../../../vendor/opencli/dist/clis/doubao/utils.js';
6
+ import { cli, Strategy } from '../../../../vendor/opencli/dist/registry.js';
7
+ function getClickReferenceEntryScript() {
8
+ return `
9
+ (() => {
10
+ const messageList = document.querySelector('[data-testid="message-list"]');
11
+ if (!messageList) return { ok: false, reason: 'no-message-list' };
12
+ const unions = Array.from(messageList.querySelectorAll('[data-testid="union_message"]'));
13
+ const lastAssistant = [...unions].reverse().find((u) =>
14
+ u.querySelector('[data-testid="receive_message"]')
15
+ );
16
+ if (!lastAssistant) return { ok: false, reason: 'no-assistant' };
17
+ const btn = lastAssistant.querySelector('[data-testid="search-reference-ui-v3"]');
18
+ if (!btn || !(btn instanceof HTMLElement)) {
19
+ const textProbe = lastAssistant.innerText || '';
20
+ const m = textProbe.match(/参考\\s*(\\d+)\\s*篇资料/);
21
+ return {
22
+ ok: false,
23
+ reason: 'no-entry',
24
+ refCountHint: m ? parseInt(m[1], 10) : null,
25
+ };
26
+ }
27
+ btn.scrollIntoView({ block: 'center', behavior: 'instant' });
28
+ btn.click();
29
+ return { ok: true };
30
+ })()
31
+ `;
32
+ }
33
+ function getExtractCitationsScript() {
34
+ return `
35
+ (() => {
36
+ const clean = (v) => (v || '')
37
+ .replace(/\\u00a0/g, ' ')
38
+ .replace(/\\n{3,}/g, '\\n\\n')
39
+ .trim();
40
+
41
+ const items = Array.from(document.querySelectorAll('[data-testid="search-text-item"]'));
42
+ return items.map((root) => {
43
+ const link =
44
+ root.querySelector('a.search-lIUYwC')
45
+ || root.querySelector('a[href^="http"]')
46
+ || root.querySelector('a[href]');
47
+ const href = link && 'href' in link ? String(link.href || '') : '';
48
+
49
+ const titleEl =
50
+ root.querySelector('.search-item-title-fLDLZw')
51
+ || root.querySelector('[class*="search-item-title"]');
52
+ const summaryEl =
53
+ root.querySelector('.search-item-summary-uNyUB_')
54
+ || root.querySelector('[class*="search-item-summary"]');
55
+ const sourceEl =
56
+ root.querySelector('.footer-title-M1Yzgt')
57
+ || root.querySelector('[class*="footer-title"]');
58
+ const indexEl =
59
+ root.querySelector('.footer-citation-PN73AP')
60
+ || root.querySelector('[class*="footer-citation"]');
61
+ const iconEl =
62
+ root.querySelector('img.footer-icon-gsIPRB')
63
+ || root.querySelector('[class*="footer-icon"]');
64
+
65
+ let index;
66
+ if (indexEl && indexEl.textContent) {
67
+ const n = parseInt(indexEl.textContent.trim().replace(/[^0-9]/g, ''), 10);
68
+ if (!Number.isNaN(n)) index = n;
69
+ }
70
+
71
+ let faviconUrl = null;
72
+ if (iconEl instanceof HTMLImageElement) {
73
+ const u = iconEl.currentSrc || iconEl.src || '';
74
+ faviconUrl = u || null;
75
+ }
76
+
77
+ const rec = {
78
+ title: clean(titleEl ? titleEl.textContent : ''),
79
+ summary: clean(summaryEl ? summaryEl.textContent : ''),
80
+ source: clean(sourceEl ? sourceEl.textContent : ''),
81
+ url: href,
82
+ faviconUrl,
83
+ };
84
+ if (index !== undefined) rec.index = index;
85
+ return rec;
86
+ });
87
+ })()
88
+ `;
89
+ }
90
+ function countCitationItemsScript() {
91
+ return `(() => document.querySelectorAll('[data-testid="search-text-item"]').length)()`;
92
+ }
93
+ function normalizeUrl(url) {
94
+ if (!url)
95
+ return '';
96
+ try {
97
+ return decodeURI(url);
98
+ }
99
+ catch {
100
+ return url;
101
+ }
102
+ }
103
+ /**
104
+ * 豆包检索会先出现「正在搜索」「找到 N 篇资料」等占位。
105
+ * 判稳改为:仅看最后一条 message_text_content;占位文本不参与终稿;流式结束用两次采样间隔(默认 5s)文本相同。
106
+ */
107
+ function isTransientAssistantReply(text) {
108
+ const t = text.trim();
109
+ if (!t)
110
+ return true;
111
+ if (t.length > 200)
112
+ return false;
113
+ if (/\n/.test(t) && t.length > 80)
114
+ return false;
115
+ // 检索中间态:仅「篇数/找到」提示、尚无正文(易与最终回答混淆)
116
+ if (t.length <= 48) {
117
+ if (/^(已)?找到\s*\d+\s*篇(资料|结果|内容)?[\s…\.]*$/u.test(t))
118
+ return true;
119
+ if (/^参考\s*\d+\s*篇资料[\s…\.]*$/u.test(t))
120
+ return true;
121
+ }
122
+ // 短句且仍以「正在…搜索/思考」为主,视为占位(避免「正在为您搜索…」等变体被当成最终答案)
123
+ if (t.length < 100 && /^正在(联网)?(搜索|检索|查找|分析|思考|生成)/u.test(t))
124
+ return true;
125
+ if (t.length < 80
126
+ && /^(搜索中|思考中|生成中|请稍候|加载中|联网搜索|正在联网)/u.test(t)) {
127
+ return true;
128
+ }
129
+ return /^(正在(联网)?(搜索|检索|查找|分析|思考|生成)[\s…\.]*|搜索中|思考中|生成中|请稍候|加载中|联网搜索[中…\.]*)$/u.test(t);
130
+ }
131
+ function sanitizeAssistantText(value, promptText) {
132
+ return value
133
+ .replace(promptText, '')
134
+ .replace(/内容由豆包 AI 生成/g, '')
135
+ .replace(/在此处拖放文件/g, '')
136
+ .replace(/文件数量:.*$/g, '')
137
+ .replace(/\{"namedChunks".*$/g, '')
138
+ .replace(/window\._SSR_DATA.*$/g, '')
139
+ .trim();
140
+ }
141
+ /** 与 Puppeteer 脚本一致:最后一条助手 message_text_content 的 innerText */
142
+ function getLastAssistantMessageTextContentScript() {
143
+ return `
144
+ (() => {
145
+ const nodes = document.querySelectorAll(
146
+ '[data-testid="receive_message"] [data-testid="message_text_content"]'
147
+ );
148
+ const last = nodes.length > 0 ? nodes[nodes.length - 1] : null;
149
+ return last ? (last.innerText || '').trim() : '';
150
+ })()
151
+ `;
152
+ }
153
+ /**
154
+ * 以 DOM 最后一条正文为准;间隔 stableGapMs 两次采样文本相同且非占位 → 流式结束(借鉴外部 Puppeteer 判稳)。
155
+ */
156
+ async function waitForLastMessageTextContentStable(page, promptText, timeoutSeconds, stableGapMs) {
157
+ const deadline = Date.now() + Math.max(1, timeoutSeconds) * 1000;
158
+ const gapSec = Math.max(0.5, stableGapMs / 1000);
159
+ let lastSubstantive = '';
160
+ let firstPoll = true;
161
+ while (Date.now() < deadline) {
162
+ const raw = await page.evaluate(getLastAssistantMessageTextContentScript());
163
+ const t1 = sanitizeAssistantText(typeof raw === 'string' ? raw : '', promptText);
164
+ if (!t1) {
165
+ const rest = (deadline - Date.now()) / 1000;
166
+ await page.wait(Math.min(firstPoll ? 1.5 : 2, Math.max(0.1, rest)));
167
+ firstPoll = false;
168
+ continue;
169
+ }
170
+ if (isTransientAssistantReply(t1)) {
171
+ const rest = (deadline - Date.now()) / 1000;
172
+ await page.wait(Math.min(2, Math.max(0.1, rest)));
173
+ firstPoll = false;
174
+ continue;
175
+ }
176
+ lastSubstantive = t1;
177
+ const remainingMs = deadline - Date.now();
178
+ if (remainingMs < stableGapMs) {
179
+ break;
180
+ }
181
+ await page.wait(gapSec);
182
+ const raw2 = await page.evaluate(getLastAssistantMessageTextContentScript());
183
+ const t2 = sanitizeAssistantText(typeof raw2 === 'string' ? raw2 : '', promptText);
184
+ if (t1 === t2 && !isTransientAssistantReply(t2)) {
185
+ return t2;
186
+ }
187
+ if (!isTransientAssistantReply(t2) && t2.length > 0) {
188
+ lastSubstantive = t2;
189
+ }
190
+ const rest = (deadline - Date.now()) / 1000;
191
+ await page.wait(Math.min(1, Math.max(0.1, rest)));
192
+ firstPoll = false;
193
+ }
194
+ return lastSubstantive;
195
+ }
196
+ async function waitForCitationPanel(page, maxSeconds) {
197
+ const deadline = Date.now() + maxSeconds * 1000;
198
+ while (Date.now() < deadline) {
199
+ const n = await page.evaluate(countCitationItemsScript());
200
+ if (typeof n === 'number' && n > 0)
201
+ return true;
202
+ await page.wait(0.5);
203
+ }
204
+ return false;
205
+ }
206
+ function truncateSummaries(records, maxChars) {
207
+ if (maxChars <= 0)
208
+ return;
209
+ for (const r of records) {
210
+ if (r.summary.length > maxChars) {
211
+ r.summary = `${r.summary.slice(0, maxChars)}…`;
212
+ }
213
+ }
214
+ }
215
+ async function collectCitationsFromPanel(page, options, verbose) {
216
+ const clickRaw = await page.evaluate(getClickReferenceEntryScript());
217
+ if (!clickRaw?.ok) {
218
+ if (verbose && clickRaw?.reason) {
219
+ process.stderr.write(`[doubao/ask-with-citations] 未打开引用面板: ${clickRaw.reason}\n`);
220
+ }
221
+ const out = { citations: [] };
222
+ if (clickRaw?.reason !== undefined)
223
+ out.clickReason = clickRaw.reason;
224
+ return out;
225
+ }
226
+ const opened = await waitForCitationPanel(page, options.panelWaitSeconds);
227
+ if (!opened) {
228
+ if (verbose) {
229
+ process.stderr.write('[doubao/ask-with-citations] 等待参考资料面板超时\n');
230
+ }
231
+ try {
232
+ await page.pressKey('Escape');
233
+ }
234
+ catch {
235
+ /* ignore */
236
+ }
237
+ return { citations: [], clickReason: 'panel-timeout' };
238
+ }
239
+ const raw = await page.evaluate(getExtractCitationsScript());
240
+ const citations = Array.isArray(raw) ? raw : [];
241
+ try {
242
+ await page.pressKey('Escape');
243
+ await page.wait(0.35);
244
+ }
245
+ catch {
246
+ /* ignore */
247
+ }
248
+ for (const c of citations) {
249
+ c.url = normalizeUrl(c.url);
250
+ if (c.faviconUrl) {
251
+ try {
252
+ c.faviconUrl = decodeURI(c.faviconUrl);
253
+ }
254
+ catch {
255
+ /* keep */
256
+ }
257
+ }
258
+ }
259
+ truncateSummaries(citations, options.summaryMaxChars);
260
+ return { citations };
261
+ }
262
+ cli({
263
+ site: 'doubao',
264
+ name: 'ask-with-citations',
265
+ description: 'Send a prompt, wait for Doubao response, and collect search reference citations (JSON in Citations column)',
266
+ domain: DOUBAO_DOMAIN,
267
+ strategy: Strategy.COOKIE,
268
+ browser: true,
269
+ navigateBefore: false,
270
+ timeoutSeconds: 240,
271
+ /** 默认 JSON:结构紧凑、省 token;需要表格可 `-f table` */
272
+ defaultFormat: 'json',
273
+ args: [
274
+ { name: 'text', required: true, positional: true, help: 'Prompt to send' },
275
+ { name: 'timeout', required: false, help: 'Max seconds to wait for answer (default: 60)', default: '60' },
276
+ {
277
+ name: 'citationSummaryMaxChars',
278
+ required: false,
279
+ help: 'Max characters per citation summary in output (default: 2000, 0 = no truncation)',
280
+ default: '2000',
281
+ },
282
+ {
283
+ name: 'citationPanelWaitSeconds',
284
+ required: false,
285
+ help: 'Max seconds to wait for reference panel items after click (default: 25)',
286
+ default: '25',
287
+ },
288
+ {
289
+ name: 'answerStableGapMs',
290
+ required: false,
291
+ help: 'Milliseconds between two samples of last assistant message_text_content for stream-done (default: 5000)',
292
+ default: '5000',
293
+ },
294
+ ],
295
+ columns: ['Role', 'Text', 'Citations'],
296
+ func: async (page, kwargs, debug) => {
297
+ const text = String(kwargs.text ?? '');
298
+ const timeout = parseInt(String(kwargs.timeout ?? '60'), 10) || 60;
299
+ const summaryMaxChars = parseInt(String(kwargs.citationSummaryMaxChars ?? '2000'), 10);
300
+ const panelWaitSeconds = parseInt(String(kwargs.citationPanelWaitSeconds ?? '25'), 10) || 25;
301
+ const answerStableGapMs = Math.max(500, parseInt(String(kwargs.answerStableGapMs ?? '5000'), 10) || 5000);
302
+ const verbose = debug === true;
303
+ await sendDoubaoMessage(page, text);
304
+ const response = await waitForLastMessageTextContentStable(page, text, timeout, answerStableGapMs);
305
+ if (!response) {
306
+ return [
307
+ { Role: 'User', Text: text, Citations: '[]' },
308
+ {
309
+ Role: 'System',
310
+ Text: `No response within ${timeout}s. Doubao may still be generating.`,
311
+ Citations: '[]',
312
+ },
313
+ ];
314
+ }
315
+ const { citations } = await collectCitationsFromPanel(page, { panelWaitSeconds, summaryMaxChars: Number.isFinite(summaryMaxChars) ? summaryMaxChars : 2000 }, verbose);
316
+ const citationsJson = JSON.stringify(citations);
317
+ return [
318
+ { Role: 'User', Text: text, Citations: '[]' },
319
+ { Role: 'Assistant', Text: response, Citations: citationsJson },
320
+ ];
321
+ },
322
+ });
323
+ //# sourceMappingURL=doubao-ask-with-citations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doubao-ask-with-citations.js","sourceRoot":"","sources":["../../../../src/integrations/opencli/commands/doubao-ask-with-citations.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { Command } from 'commander';
2
+ /** 与 Commander 子命令上 -f/--format、-v/--verbose 对齐的选项 */
3
+ export type OpencliCliFormatOptions = {
4
+ format: string;
5
+ verbose: boolean;
6
+ };
7
+ /**
8
+ * 执行已注册在 opencli registry 中的命令并渲染输出(须在 bootstrapOpencli 之后调用)。
9
+ */
10
+ export declare function executeOpencliRegistryCommand(registryKey: string, kwargs: Record<string, string | boolean>, command: Command, cliOptions: OpencliCliFormatOptions): Promise<void>;
11
+ //# sourceMappingURL=execute-registry-command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execute-registry-command.d.ts","sourceRoot":"","sources":["../../../src/integrations/opencli/execute-registry-command.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKzC,sDAAsD;AACtD,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF;;GAEG;AACH,wBAAsB,6BAA6B,CACjD,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,EACxC,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,uBAAuB,GAClC,OAAO,CAAC,IAAI,CAAC,CAwCf"}
@@ -0,0 +1,45 @@
1
+ import { executeCommand } from '../../../vendor/opencli/dist/execution.js';
2
+ import { render } from '../../../vendor/opencli/dist/output.js';
3
+ import { fullName, getRegistry } from '../../../vendor/opencli/dist/registry.js';
4
+ /**
5
+ * 执行已注册在 opencli registry 中的命令并渲染输出(须在 bootstrapOpencli 之后调用)。
6
+ */
7
+ export async function executeOpencliRegistryCommand(registryKey, kwargs, command, cliOptions) {
8
+ const cmd = getRegistry().get(registryKey);
9
+ if (!cmd) {
10
+ console.error(`未注册 ${registryKey}:请在 vendor/opencli 目录执行 npm install && npm run build。`);
11
+ process.exitCode = 1;
12
+ return;
13
+ }
14
+ const verbose = cliOptions.verbose;
15
+ const start = Date.now();
16
+ try {
17
+ const result = await executeCommand(cmd, kwargs, verbose);
18
+ if (result === null || result === undefined)
19
+ return;
20
+ const resolved = getRegistry().get(fullName(cmd)) ?? cmd;
21
+ let format = cliOptions.format;
22
+ const formatExplicit = command.getOptionValueSource('format') === 'cli';
23
+ if (!formatExplicit && format === 'table' && resolved.defaultFormat) {
24
+ format = resolved.defaultFormat;
25
+ }
26
+ const renderOpts = {
27
+ fmt: format,
28
+ fmtExplicit: formatExplicit,
29
+ title: `${resolved.site}/${resolved.name}`,
30
+ elapsed: (Date.now() - start) / 1000,
31
+ source: fullName(resolved),
32
+ };
33
+ if (resolved.columns !== undefined)
34
+ renderOpts.columns = resolved.columns;
35
+ const footerExtra = resolved.footerExtra?.(kwargs);
36
+ if (footerExtra !== undefined)
37
+ renderOpts.footerExtra = footerExtra;
38
+ render(result, renderOpts);
39
+ }
40
+ catch (err) {
41
+ console.error(err instanceof Error ? err.message : String(err));
42
+ process.exitCode = 1;
43
+ }
44
+ }
45
+ //# sourceMappingURL=execute-registry-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execute-registry-command.js","sourceRoot":"","sources":["../../../src/integrations/opencli/execute-registry-command.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,2CAA2C,CAAC;AAC3E,OAAO,EAAE,MAAM,EAAsB,MAAM,wCAAwC,CAAC;AACpF,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,0CAA0C,CAAC;AAQjF;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,WAAmB,EACnB,MAAwC,EACxC,OAAgB,EAChB,UAAmC;IAEnC,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC3C,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,CAAC,KAAK,CACX,OAAO,WAAW,uDAAuD,CAC1E,CAAC;QACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC;IACnC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEzB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QAC1D,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO;QAEpD,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC;QACzD,IAAI,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;QAC/B,MAAM,cAAc,GAAG,OAAO,CAAC,oBAAoB,CAAC,QAAQ,CAAC,KAAK,KAAK,CAAC;QACxE,IAAI,CAAC,cAAc,IAAI,MAAM,KAAK,OAAO,IAAI,QAAQ,CAAC,aAAa,EAAE,CAAC;YACpE,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC;QAClC,CAAC;QAED,MAAM,UAAU,GAAkB;YAChC,GAAG,EAAE,MAAM;YACX,WAAW,EAAE,cAAc;YAC3B,KAAK,EAAE,GAAG,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI,EAAE;YAC1C,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,IAAI;YACpC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC;SAC3B,CAAC;QACF,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS;YAAE,UAAU,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;QAC1E,MAAM,WAAW,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC;QACnD,IAAI,WAAW,KAAK,SAAS;YAAE,UAAU,CAAC,WAAW,GAAG,WAAW,CAAC;QAEpE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC7B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QAChE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { Command } from 'commander';
2
+ export type DoubaoAskWithCitationsCliOptions = {
3
+ timeout: string;
4
+ citationSummaryMaxChars: string;
5
+ citationPanelWaitSeconds: string;
6
+ answerStableGapMs: string;
7
+ format: string;
8
+ verbose: boolean;
9
+ };
10
+ /**
11
+ * 豆包 ask-with-citations:企业鉴权后执行 registry `doubao/ask-with-citations`(正文 + Citations JSON)。
12
+ */
13
+ export declare function runDoubaoAskWithCitations(prompt: string, options: DoubaoAskWithCitationsCliOptions, command: Command): Promise<void>;
14
+ //# sourceMappingURL=ask-with-citations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ask-with-citations.d.ts","sourceRoot":"","sources":["../../../src/sites/doubao/ask-with-citations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,MAAM,MAAM,gCAAgC,GAAG;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,uBAAuB,EAAE,MAAM,CAAC;IAChC,wBAAwB,EAAE,MAAM,CAAC;IACjC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF;;GAEG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,gCAAgC,EACzC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,IAAI,CAAC,CAqBf"}
@@ -0,0 +1,21 @@
1
+ import { executeOpencliRegistryCommand } from '../../integrations/opencli/execute-registry-command.js';
2
+ import { auth } from '../../utils/config.js';
3
+ /**
4
+ * 豆包 ask-with-citations:企业鉴权后执行 registry `doubao/ask-with-citations`(正文 + Citations JSON)。
5
+ */
6
+ export async function runDoubaoAskWithCitations(prompt, options, command) {
7
+ if (!auth.getEnterpriseKey()) {
8
+ console.log('访问受限。请先使用 huyuan-ai-cli login <your-key> 进行授权。');
9
+ process.exitCode = 1;
10
+ return;
11
+ }
12
+ const kwargs = {
13
+ text: prompt,
14
+ timeout: options.timeout ?? '60',
15
+ citationSummaryMaxChars: options.citationSummaryMaxChars ?? '2000',
16
+ citationPanelWaitSeconds: options.citationPanelWaitSeconds ?? '25',
17
+ answerStableGapMs: options.answerStableGapMs ?? '5000',
18
+ };
19
+ await executeOpencliRegistryCommand('doubao/ask-with-citations', kwargs, command, { format: options.format, verbose: options.verbose });
20
+ }
21
+ //# sourceMappingURL=ask-with-citations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ask-with-citations.js","sourceRoot":"","sources":["../../../src/sites/doubao/ask-with-citations.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,6BAA6B,EAAE,MAAM,wDAAwD,CAAC;AACvG,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAW7C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,MAAc,EACd,OAAyC,EACzC,OAAgB;IAEhB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;QAC9D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAqC;QAC/C,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,IAAI;QAChC,uBAAuB,EAAE,OAAO,CAAC,uBAAuB,IAAI,MAAM;QAClE,wBAAwB,EAAE,OAAO,CAAC,wBAAwB,IAAI,IAAI;QAClE,iBAAiB,EAAE,OAAO,CAAC,iBAAiB,IAAI,MAAM;KACvD,CAAC;IAEF,MAAM,6BAA6B,CACjC,2BAA2B,EAC3B,MAAM,EACN,OAAO,EACP,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CACrD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { Command } from 'commander';
2
+ export type DoubaoAskCliOptions = {
3
+ timeout: string;
4
+ format: string;
5
+ verbose: boolean;
6
+ };
7
+ /**
8
+ * 豆包 ask:企业鉴权后执行 opencli registry 中的 doubao/ask。
9
+ */
10
+ export declare function runDoubaoAsk(prompt: string, options: DoubaoAskCliOptions, command: Command): Promise<void>;
11
+ //# sourceMappingURL=ask.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ask.d.ts","sourceRoot":"","sources":["../../../src/sites/doubao/ask.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIzC,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF;;GAEG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,mBAAmB,EAC5B,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,IAAI,CAAC,CAkBf"}
@@ -0,0 +1,18 @@
1
+ import { executeOpencliRegistryCommand } from '../../integrations/opencli/execute-registry-command.js';
2
+ import { auth } from '../../utils/config.js';
3
+ /**
4
+ * 豆包 ask:企业鉴权后执行 opencli registry 中的 doubao/ask。
5
+ */
6
+ export async function runDoubaoAsk(prompt, options, command) {
7
+ if (!auth.getEnterpriseKey()) {
8
+ console.log("访问受限。请先使用 huyuan-ai-cli login <your-key> 进行授权。");
9
+ process.exitCode = 1;
10
+ return;
11
+ }
12
+ const kwargs = {
13
+ text: prompt,
14
+ timeout: options.timeout ?? '60',
15
+ };
16
+ await executeOpencliRegistryCommand('doubao/ask', kwargs, command, { format: options.format, verbose: options.verbose });
17
+ }
18
+ //# sourceMappingURL=ask.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ask.js","sourceRoot":"","sources":["../../../src/sites/doubao/ask.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,6BAA6B,EAAE,MAAM,wDAAwD,CAAC;AACvG,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAQ7C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAc,EACd,OAA4B,EAC5B,OAAgB;IAEhB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;QAC9D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAqC;QAC/C,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,IAAI;KACjC,CAAC;IAEF,MAAM,6BAA6B,CACjC,YAAY,EACZ,MAAM,EACN,OAAO,EACP,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CACrD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { Command } from 'commander';
2
+ /** 注册 `huyuan-ai-cli doubao ...` 子命令(对齐 opencli 的 site 层级) */
3
+ export declare function registerDoubao(program: Command): void;
4
+ //# sourceMappingURL=register.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../src/sites/doubao/register.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOzC,8DAA8D;AAC9D,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmDrD"}
@@ -0,0 +1,30 @@
1
+ import { runDoubaoAsk } from './ask.js';
2
+ import { runDoubaoAskWithCitations, } from './ask-with-citations.js';
3
+ /** 注册 `huyuan-ai-cli doubao ...` 子命令(对齐 opencli 的 site 层级) */
4
+ export function registerDoubao(program) {
5
+ const doubao = program.command('doubao').description('豆包相关命令(基于 OpenCLI)');
6
+ doubao
7
+ .command('ask')
8
+ .description('调用豆包对话 (需要企业授权)')
9
+ .argument('<prompt>', '提示内容')
10
+ .option('--timeout <seconds>', '等待回复的最长时间(秒)', '60')
11
+ .option('-f, --format <fmt>', '输出格式: table, plain, json, yaml, md, csv', 'table')
12
+ .option('-v, --verbose', '调试输出', false)
13
+ .action(async (prompt, options, command) => {
14
+ await runDoubaoAsk(prompt, options, command);
15
+ });
16
+ doubao
17
+ .command('ask-with-citations')
18
+ .description('调用豆包对话并采集「参考资料」引用为 JSON(需要企业授权)')
19
+ .argument('<prompt>', '提示内容')
20
+ .option('--timeout <seconds>', '等待回复的最长时间(秒)', '60')
21
+ .option('--citation-summary-max-chars <n>', '每条引用摘要的最大字符数(0 表示不截断)', '2000')
22
+ .option('--citation-panel-wait-seconds <n>', '点击「参考 N 篇资料」后等待面板出现的最长时间(秒)', '25')
23
+ .option('--answer-stable-gap-ms <ms>', '判定助手正文流式结束:两次采样最后一条 message_text_content 的间隔(毫秒,默认 5000)', '5000')
24
+ .option('-f, --format <fmt>', '输出格式: json, table, plain, yaml, md, csv(默认 json)', 'json')
25
+ .option('-v, --verbose', '调试输出', false)
26
+ .action(async (prompt, options, command) => {
27
+ await runDoubaoAskWithCitations(prompt, options, command);
28
+ });
29
+ }
30
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","sourceRoot":"","sources":["../../../src/sites/doubao/register.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAA4B,MAAM,UAAU,CAAC;AAClE,OAAO,EACL,yBAAyB,GAE1B,MAAM,yBAAyB,CAAC;AAEjC,8DAA8D;AAC9D,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,oBAAoB,CAAC,CAAC;IAE3E,MAAM;SACH,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,iBAAiB,CAAC;SAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;SAC5B,MAAM,CAAC,qBAAqB,EAAE,cAAc,EAAE,IAAI,CAAC;SACnD,MAAM,CAAC,oBAAoB,EAAE,yCAAyC,EAAE,OAAO,CAAC;SAChF,MAAM,CAAC,eAAe,EAAE,MAAM,EAAE,KAAK,CAAC;SACtC,MAAM,CACL,KAAK,EACH,MAAc,EACd,OAA4B,EAC5B,OAAgB,EAChB,EAAE;QACF,MAAM,YAAY,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC,CACF,CAAC;IAEJ,MAAM;SACH,OAAO,CAAC,oBAAoB,CAAC;SAC7B,WAAW,CAAC,iCAAiC,CAAC;SAC9C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;SAC5B,MAAM,CAAC,qBAAqB,EAAE,cAAc,EAAE,IAAI,CAAC;SACnD,MAAM,CACL,kCAAkC,EAClC,uBAAuB,EACvB,MAAM,CACP;SACA,MAAM,CACL,mCAAmC,EACnC,6BAA6B,EAC7B,IAAI,CACL;SACA,MAAM,CACL,6BAA6B,EAC7B,0DAA0D,EAC1D,MAAM,CACP;SACA,MAAM,CAAC,oBAAoB,EAAE,kDAAkD,EAAE,MAAM,CAAC;SACxF,MAAM,CAAC,eAAe,EAAE,MAAM,EAAE,KAAK,CAAC;SACtC,MAAM,CACL,KAAK,EACH,MAAc,EACd,OAAyC,EACzC,OAAgB,EAChB,EAAE;QACF,MAAM,yBAAyB,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC5D,CAAC,CACF,CAAC;AACN,CAAC"}
@@ -0,0 +1,23 @@
1
+ import Conf from 'conf';
2
+ /** 与 ~/.huyuan-ai/config.json 对齐的存储形状 */
3
+ export type HuyuanConfig = {
4
+ enterpriseKey?: string;
5
+ skillHubToken?: string;
6
+ tempToken?: string;
7
+ };
8
+ export declare const config: Conf<HuyuanConfig>;
9
+ /** 配置目录:~/.huyuan-ai */
10
+ export declare const CONFIG_DIR: string;
11
+ /** 配置文件绝对路径(通常为 ~/.huyuan-ai/config.json) */
12
+ export declare const CONFIG_PATH: string;
13
+ export declare const auth: {
14
+ setEnterpriseKey: (key: string) => void;
15
+ getEnterpriseKey: () => string | undefined;
16
+ setSkillHubToken: (token: string) => void;
17
+ getSkillHubToken: () => string | undefined;
18
+ setTempToken: (token: string) => void;
19
+ getTempToken: () => string | undefined;
20
+ hasEnterpriseKey: () => boolean;
21
+ clear: () => void;
22
+ };
23
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAqB,MAAM,MAAM,CAAC;AAIzC,yCAAyC;AACzC,MAAM,MAAM,YAAY,GAAG;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAUF,eAAO,MAAM,MAAM,oBAQjB,CAAC;AAEH,wBAAwB;AACxB,eAAO,MAAM,UAAU,QAAY,CAAC;AAEpC,6CAA6C;AAC7C,eAAO,MAAM,WAAW,QAAc,CAAC;AAEvC,eAAO,MAAM,IAAI;4BACS,MAAM;;8BAKJ,MAAM;;0BAKV,MAAM;;;;CAU7B,CAAC"}
@@ -0,0 +1,41 @@
1
+ import Conf, {} from 'conf';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ const configDir = path.join(os.homedir(), '.huyuan-ai');
5
+ const schema = {
6
+ enterpriseKey: { type: 'string' },
7
+ skillHubToken: { type: 'string' },
8
+ tempToken: { type: 'string' },
9
+ };
10
+ export const config = new Conf({
11
+ projectName: 'huyuan-ai',
12
+ cwd: configDir,
13
+ configName: 'config',
14
+ schema,
15
+ rootSchema: {
16
+ additionalProperties: false,
17
+ },
18
+ });
19
+ /** 配置目录:~/.huyuan-ai */
20
+ export const CONFIG_DIR = configDir;
21
+ /** 配置文件绝对路径(通常为 ~/.huyuan-ai/config.json) */
22
+ export const CONFIG_PATH = config.path;
23
+ export const auth = {
24
+ setEnterpriseKey: (key) => {
25
+ config.set('enterpriseKey', key);
26
+ },
27
+ getEnterpriseKey: () => config.get('enterpriseKey'),
28
+ setSkillHubToken: (token) => {
29
+ config.set('skillHubToken', token);
30
+ },
31
+ getSkillHubToken: () => config.get('skillHubToken'),
32
+ setTempToken: (token) => {
33
+ config.set('tempToken', token);
34
+ },
35
+ getTempToken: () => config.get('tempToken'),
36
+ hasEnterpriseKey: () => config.has('enterpriseKey'),
37
+ clear: () => {
38
+ config.clear();
39
+ },
40
+ };
41
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,EAAE,EAAe,MAAM,MAAM,CAAC;AACzC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAS7B,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,CAAC;AAExD,MAAM,MAAM,GAAyB;IACnC,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IACjC,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IACjC,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;CAC9B,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,IAAI,CAAe;IAC3C,WAAW,EAAE,WAAW;IACxB,GAAG,EAAE,SAAS;IACd,UAAU,EAAE,QAAQ;IACpB,MAAM;IACN,UAAU,EAAE;QACV,oBAAoB,EAAE,KAAK;KAC5B;CACF,CAAC,CAAC;AAEH,wBAAwB;AACxB,MAAM,CAAC,MAAM,UAAU,GAAG,SAAS,CAAC;AAEpC,6CAA6C;AAC7C,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC;AAEvC,MAAM,CAAC,MAAM,IAAI,GAAG;IAClB,gBAAgB,EAAE,CAAC,GAAW,EAAE,EAAE;QAChC,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;IACnC,CAAC;IACD,gBAAgB,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC;IAEnD,gBAAgB,EAAE,CAAC,KAAa,EAAE,EAAE;QAClC,MAAM,CAAC,GAAG,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;IACrC,CAAC;IACD,gBAAgB,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC;IAEnD,YAAY,EAAE,CAAC,KAAa,EAAE,EAAE;QAC9B,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IACjC,CAAC;IACD,YAAY,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC;IAE3C,gBAAgB,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC;IAEnD,KAAK,EAAE,GAAG,EAAE;QACV,MAAM,CAAC,KAAK,EAAE,CAAC;IACjB,CAAC;CACF,CAAC"}