@3-/aiapi 0.1.75 → 0.1.77

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/check/GEN.js ADDED
@@ -0,0 +1,41 @@
1
+ import TYPE from '../TYPE.js';
2
+
3
+ export default {
4
+ type: TYPE.ARRAY,
5
+ description: '基于对话分析生成的、可进行外部搜索验证的投资洞察列表(请把公司提及的个案数据,转为对行业搜索研究的命题)',
6
+ minItems: 0,
7
+ items: {
8
+ type: TYPE.OBJECT,
9
+ properties: {
10
+ title: {
11
+ type: TYPE.STRING,
12
+ description: '简短的标题,概述研究内容'
13
+ },
14
+ question: {
15
+ type: TYPE.STRING,
16
+ description: '从对话中提炼出的、具有明确事实属性且可通过外部搜索验证的关键行业洞察,是可以被证明或者证伪的命题。请避免无法验证的主观形容词。'
17
+ },
18
+ zh: {
19
+ type: TYPE.ARRAY,
20
+ description: '用于验证该洞察真伪的搜索关键词列表(中文)',
21
+ minItems: 0,
22
+ items: {
23
+ type: TYPE.STRING
24
+ }
25
+ },
26
+ en: {
27
+ type: TYPE.ARRAY,
28
+ description: '用于验证该洞察真伪的搜索关键词列表(英文)',
29
+ minItems: 0,
30
+ items: {
31
+ type: TYPE.STRING
32
+ }
33
+ },
34
+ reason: {
35
+ type: TYPE.STRING,
36
+ description: '分析为何搜索研究该洞察对判断决策至关重要'
37
+ }
38
+ },
39
+ required: ['title', 'question', 'zh', 'en', 'reason']
40
+ }
41
+ };
@@ -0,0 +1,57 @@
1
+ import TYPE from '../TYPE.js';
2
+
3
+ export default {
4
+ type: TYPE.OBJECT,
5
+ properties: {
6
+ 研究: {
7
+ type: TYPE.ARRAY,
8
+ minItems: 1,
9
+ description: `请执行以下结构化的研究报告撰写任务:
10
+ 1. 章节拆分规划:首先,请根据研究主题的内在逻辑,将报告内容拆分为3-5个主要章节,每个章节需有明确的主题和研究范围。
11
+ 2. 研究过程汇报:其次,详细记录并汇报研究实施的完整过程,包括但不限于:研究方法选择、数据收集途径、分析工具使用、关键节点时间线等。
12
+ 3. 资料汇总整理:然后,在最后一章中,基于汇总的资料进行严谨的逻辑推理,分析数据间的关联性和规律,最终得出明确、有依据的研究结论。`,
13
+ items: {
14
+ type: TYPE.OBJECT,
15
+ required: ['title', 'md'],
16
+ properties: {
17
+ title: {
18
+ type: TYPE.STRING,
19
+ description: '章节标题'
20
+ },
21
+ md: {
22
+ type: TYPE.STRING,
23
+ description: '章节正文,markdown格式(禁止包含标题)'
24
+ }
25
+ }
26
+ }
27
+ },
28
+ 结论: {
29
+ type: TYPE.STRING,
30
+ description: '一句话概述研究结论(支持还是不支持命题)'
31
+ },
32
+ 文献: {
33
+ type: TYPE.ARRAY,
34
+ description: '参考资料',
35
+ minItems: 1,
36
+ items: {
37
+ type: TYPE.OBJECT,
38
+ required: ['title', 'brief', 'url'],
39
+ properties: {
40
+ title: {
41
+ type: TYPE.STRING,
42
+ description: '标题'
43
+ },
44
+ brief: {
45
+ type: TYPE.STRING,
46
+ description: '概述文章内容'
47
+ },
48
+ url: {
49
+ type: TYPE.STRING,
50
+ description: '链接'
51
+ }
52
+ }
53
+ }
54
+ }
55
+ },
56
+ required: ['结论', '研究', "文献"]
57
+ };
@@ -1,8 +1,13 @@
1
1
  #!/usr/bin/env -S node --trace-uncaught --expose-gc --unhandled-rejections=strict --experimental-wasm-modules
2
2
  import fmtJson from './fmtJson.js';
3
3
 
4
- import fmtJsonMd from './fmtJsonMd.js';
4
+ import partition from './partition.js';
5
5
 
6
6
  export default async(chat, txt) => {
7
- return fmtJsonMd((await fmtJson(chat, txt)));
7
+ var pli;
8
+ pli = (await partition(chat, txt));
9
+ if (!pli.length) {
10
+ return '';
11
+ }
12
+ return fmtJson(chat, pli);
8
13
  };
package/fmtJson.js ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env -S node --trace-uncaught --expose-gc --unhandled-rejections=strict --experimental-wasm-modules
2
+ import fmtSeg from './fmtSeg.js';
3
+
4
+ import fmtJsonMd from './fmtJsonMd.js';
5
+
6
+ export default async(chat, pli) => {
7
+ return fmtJsonMd((await Promise.all(pli.map(async([title, li]) => {
8
+ console.log('\n---\n→ ' + title + '\n' + li.join('\n') + '\n---\n');
9
+ return [title, (await fmtSeg(chat, li.join('\n')))];
10
+ }))));
11
+ };
@@ -3,6 +3,8 @@ var txtFmt;
3
3
 
4
4
  import TxtLi from '@3-/txt_li';
5
5
 
6
+ import refmt from './refmt.js';
7
+
6
8
  txtFmt = (txt) => {
7
9
  return TxtLi(txt).join('\n\n');
8
10
  };
@@ -12,15 +14,15 @@ export default (title_json_li) => {
12
14
  md_li = [];
13
15
  for (x of title_json_li) {
14
16
  [title, li] = x;
15
- md_li.push('# ' + title);
17
+ md_li.push('## ' + title);
16
18
  for (y of li) {
17
19
  ({题, 问, 答} = y);
18
20
  答 = txtFmt(答).trim();
19
21
  if ((答.startsWith('1. ')) || 答.endsWith(':') || 答.endsWith(':')) {
20
22
  答 = '\n' + 答;
21
23
  }
22
- md_li.push('## ' + 题 + '\n问: ' + txtFmt(问).trimEnd() + '\n\n答: ' + 答 + '\n');
24
+ md_li.push('### ' + 题 + '\n问: ' + txtFmt(问).trimEnd() + '\n\n答: ' + 答 + '\n');
23
25
  }
24
26
  }
25
- return md_li.join('\n');
27
+ return md_li.map(refmt).join('\n');
26
28
  };
@@ -34,7 +34,10 @@ export default (token_li, model = 'gemini-3-flash-preview') => { // model='gemi
34
34
  if (schema) {
35
35
  body.generationConfig = {
36
36
  responseMimeType: 'application/json',
37
- responseJsonSchema: schema
37
+ responseJsonSchema: schema,
38
+ thinkingConfig: {
39
+ thinkingLevel: 'high'
40
+ }
38
41
  };
39
42
  }
40
43
  if (option) {
package/package.json CHANGED
@@ -1,31 +1 @@
1
- {
2
- "name": "@3-/aiapi",
3
- "version": "0.1.75",
4
- "repository": {
5
- "type": "git",
6
- "url": "git+https://atomgit.com/i18n/lib.git"
7
- },
8
- "homepage": "https://atomgit.com/i18n/lib/tree/dev/aiapi",
9
- "author": "i18n.site@gmail.com",
10
- "license": "MulanPSL-2.0",
11
- "exports": {
12
- ".": "./lib/lib.js",
13
- "./*": "./lib/*"
14
- },
15
- "files": [
16
- "lib/*"
17
- ],
18
- "devDependencies": {
19
- "@3-/read": "^0.1.4"
20
- },
21
- "scripts": {},
22
- "type": "module",
23
- "dependencies": {
24
- "@3-/retry": "^0.0.2",
25
- "@3-/rm_cn_space": "^0.1.1",
26
- "@3-/sleep": "^0.0.4",
27
- "@3-/txt_li": "^0.1.5",
28
- "@3-/utf8": "^0.0.4",
29
- "lodash-es": "^4.17.21"
30
- }
31
- }
1
+ {"name":"@3-/aiapi","version":"0.1.77","repository":{"type":"git","url":"git+https://atomgit.com/i18n/lib.git"},"homepage":"https://atomgit.com/i18n/lib/tree/dev/aiapi","author":"i18n.site@gmail.com","license":"MulanPSL-2.0","exports":{".":"./lib.js","./*":"./*"},"files":["./*"],"devDependencies":{"@3-/read":"^0.1.4"},"scripts":{},"type":"module","dependencies":{"@3-/retry":"^0.0.2","@3-/rm_cn_space":"^0.1.1","@3-/sleep":"^0.0.4","@3-/txt_li":"^0.1.5","@3-/utf8":"^0.0.4","lodash-es":"^4.17.21"}}
@@ -1,5 +1,6 @@
1
1
  import seg from "./seg.js";
2
2
  import txtLi from "@3-/txt_li";
3
+ import rmCnSpace from "@3-/rm_cn_space";
3
4
 
4
5
  const partition = async (li, title_number, remain_seg) => {
5
6
  const order = title_number.sort((a, b) => a[1] - b[1]);
@@ -41,6 +42,9 @@ const partition = async (li, title_number, remain_seg) => {
41
42
  };
42
43
 
43
44
  export default async (chat, txt) => {
44
- const li = txtLi(txt);
45
+ if (!txt) {
46
+ return [];
47
+ }
48
+ const li = txtLi(txt).map((i) => rmCnSpace(i));
45
49
  return partition(li, await seg(chat, li), repartition(chat, li.length));
46
50
  };
package/refmt.js ADDED
@@ -0,0 +1,2 @@
1
+ export default (txt) =>
2
+ txt.replaceAll("\\n", "\n").replaceAll("“", "「").replaceAll("”", "」");
package/researchFmt.js ADDED
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env -S node --trace-uncaught --expose-gc --unhandled-rejections=strict --experimental-wasm-modules
2
+ import fmtJson from './fmtJson.js';
3
+
4
+ import partition from './partition.js';
5
+
6
+ import GEN from './check/GEN.js';
7
+
8
+ import SEARCH from './check/SEARCH.js';
9
+
10
+ import refmt from './refmt.js';
11
+
12
+ export default async(chat, txt) => {
13
+ var fmt, gen_txt, pli, search;
14
+ pli = (await partition(chat, txt));
15
+ if (!pli.length) {
16
+ return [];
17
+ }
18
+ fmt = fmtJson(chat, pli);
19
+ gen_txt = pli.map(([title, li]) => {
20
+ return '# ' + title + '\n' + li.join('\n');
21
+ }).join('\n');
22
+ search = Promise.all(((await chat(gen_txt, GEN, "你是专业的风险投资人"))).map(async(i) => {
23
+ var body, en, question, reason, title, zh, 文献, 研究, 结论;
24
+ // console.log i
25
+ ({title, question, zh, en, reason} = i);
26
+ body = title + '\n研究命题: ' + question + '\n中文搜索词: ' + zh + '\n英文搜索词: ' + en;
27
+ console.log('\n# ' + body);
28
+ ({结论, 研究, 文献} = (await chat('请基于搜索,对以下命题深度研究:\n' + body, SEARCH, '利用搜索工具进行客观理性的研究分析', {
29
+ tools: [
30
+ {
31
+ google_search: {}
32
+ },
33
+ {
34
+ url_context: {}
35
+ }
36
+ ]
37
+ })));
38
+ return '## ' + title.trim() + '\n\n**<u>问题:</u>** ' + question.trim() + '\n\n**<u>结论</u>:** ' + 结论.trim() + '\n\n' + 研究.map(({title, md}) => {
39
+ return '### ' + title + '\n\n' + md;
40
+ }).join('\n') + '\n\n### 参考资料\n\n' + 文献.map(({title, brief, url}, pos) => {
41
+ return (pos + 1) + '. [' + title + '](' + url + ') : ' + brief;
42
+ }).join('\n');
43
+ }));
44
+ [fmt, search] = (await Promise.all([fmt, search]));
45
+ if (search.length) {
46
+ fmt += '# 机器投研\n\n' + search.map(refmt).join('\n');
47
+ }
48
+ return fmt;
49
+ };
@@ -4,29 +4,30 @@ import TYPE from './TYPE.js';
4
4
  export default async(chat, txt_li) => {
5
5
  var split_li, 提示词;
6
6
  提示词 = `下文第1列为行号,第2列为对话内容,以tab分隔。
7
- 请划分章节,每章以提问开始,包含几个问答,不要太长也不要太短,千字左右一章。
8
- 输出章节标题和每章首个问题的行号及原文,输出格式为JSON数组:\n` + txt_li.map((i, pos) => {
7
+ 请划分章节,每章不要太长也不要太短,千字左右一章。
8
+ 输出章节标题、每章最后一句号的行号。
9
+ 输出格式为json数组:\n` + txt_li.map((i, pos) => {
9
10
  return (pos + 1) + '\t' + i.trim();
10
11
  }).join('\n');
11
12
  split_li = (await chat(提示词, {
12
13
  type: TYPE.ARRAY,
13
- description: '章节和行号的列表',
14
+ description: '拆分文章为多个章节,每个章节包含一系列问答对',
14
15
  minItems: 1,
15
16
  items: {
16
17
  type: TYPE.OBJECT,
17
18
  properties: {
18
19
  题: {
19
- description: '章节标题,要概括章节内容',
20
+ description: '章节标题(只写标题,不写注释)',
20
21
  type: TYPE.STRING
21
22
  },
22
23
  行: {
23
- description: '该章最后一行的行号',
24
+ description: '该章最后一句的行号',
24
25
  type: TYPE.INTEGER
25
26
  }
26
27
  },
27
28
  required: ['题', '行']
28
29
  }
29
- }, '你是专业资深的秘书'));
30
+ }, '你是专业资深的杂志编辑'));
30
31
  return split_li.map((i) => {
31
32
  return [i.题, i.行];
32
33
  });
package/README.mdt DELETED
@@ -1 +0,0 @@
1
- # @3-/aiapi
package/lib/README.md DELETED
@@ -1 +0,0 @@
1
- # @3-/aiapi
package/lib/factCheck.js DELETED
@@ -1,189 +0,0 @@
1
- #!/usr/bin/env -S node --trace-uncaught --expose-gc --unhandled-rejections=strict --experimental-wasm-modules
2
- var PREFIX, SHOW_KIND, addUrl, circle, realUrl, txtLi, urlLi;
3
-
4
- import retry from '@3-/retry';
5
-
6
- import utf8d from '@3-/utf8/utf8d.js';
7
-
8
- import utf8e from '@3-/utf8/utf8e.js';
9
-
10
- // @3-/read
11
- // @3-/write
12
- SHOW_KIND = ['严重失实', '不正确'];
13
-
14
- PREFIX = `对下文问答中提及的事实做核查(不核查观点)。
15
- 数据偏差不超过30%都当做基本一致,找不到信息当无法核实。
16
- 必须搜索到明确的证伪证据并才算失实。
17
- 只输出不正确/严重失实的核查。
18
- 输出文本必须是简体中文,格式如下:
19
- - id:
20
- 标题: 要简短,几个词即可
21
- 观点:
22
- 事实: 须标注搜索到的事实网页, 完整描述观点错误所在(不引用其他核查)
23
- 失实度: ${SHOW_KIND.join(' / ')} / 基本一致 / 无法核实
24
- ---\n`;
25
-
26
- realUrl = async(url) => {
27
- var err, r, status;
28
- if (url.startsWith('http')) {
29
- try {
30
- r = (await fetch(url, {
31
- method: 'HEAD',
32
- redirect: 'follow'
33
- }));
34
- ({status} = r);
35
- if (status === 200) {
36
- ({url} = r);
37
- } else {
38
- console.error(status + ' :' + url);
39
- }
40
- } catch (error) {
41
- err = error;
42
- console.error(err);
43
- }
44
- }
45
- return url;
46
- };
47
-
48
- circle = (num) => {
49
- switch (false) {
50
- case !(num > 0 && num <= 10):
51
- return String.fromCodePoint(0x245F + num);
52
- default:
53
- return `[${num}]`;
54
- }
55
- };
56
-
57
- urlLi = (id_li, url_li) => {
58
- var i, r;
59
- r = [];
60
- for (i of id_li) {
61
- r.push('[' + circle(i + 1) + '](' + url_li[i] + ')');
62
- }
63
- return r.join('');
64
- };
65
-
66
- addUrl = (text, items) => {
67
- var bin, chunks, end, entry, j, len, output, pos, push, sorted, start;
68
- output = '';
69
- push = (bin) => {
70
- output += utf8d(bin);
71
- };
72
- pos = 0;
73
- sorted = items.sort(function(a, b) {
74
- return a.segment.startIndex - b.segment.startIndex;
75
- });
76
- bin = utf8e(text);
77
- for (j = 0, len = sorted.length; j < len; j++) {
78
- entry = sorted[j];
79
- ({
80
- segment: {
81
- startIndex: start,
82
- endIndex: end
83
- },
84
- groundingChunkIndices: chunks
85
- } = entry);
86
- if (start > pos) {
87
- push(bin.slice(pos, start));
88
- }
89
- push(bin.slice(start, end));
90
- output += chunks;
91
- pos = end;
92
- }
93
- if (pos < bin.length) {
94
- push(bin.slice(pos));
95
- }
96
- return output;
97
- };
98
-
99
- txtLi = (txt) => {
100
- var all_tag, i, id, pre, r, reset, t, tag, trim, txt_li;
101
- r = [];
102
- reset = () => {
103
- all_tag = new Set(['标题', '观点', '事实', '失实度']);
104
- if (t) {
105
- r.push(t);
106
- }
107
- pre = t = void 0;
108
- };
109
- txt_li = txt.replaceAll('**', '').split('\n');
110
- out: //;
111
- for (i of txt_li) {
112
- if (i.startsWith('- id:')) {
113
- reset();
114
- id = parseInt(i.slice(5).trim());
115
- if (id) {
116
- t = {id};
117
- }
118
- } else if (t) {
119
- trim = i.replace('- ', '').trimStart();
120
- for (tag of all_tag) {
121
- if (trim.startsWith(tag + ':')) {
122
- all_tag.delete(tag);
123
- pre = tag;
124
- t[tag] = trim.slice(tag.length + 1).trim();
125
- if (tag === '失实度' && all_tag.size === 0) {
126
- reset();
127
- }
128
- continue out;
129
- }
130
- }
131
- if (pre && trim) {
132
- t[pre] += '\n' + trim;
133
- }
134
- }
135
- }
136
- if (t) {
137
- r.push(t);
138
- }
139
- return r;
140
- };
141
-
142
- export default retry(async(chat, li) => {
143
- var content, groundingChunks, groundingSupports, i, map, msg, out, ref, ref1, uri, url_li, x;
144
- msg = PREFIX + li.map((i, pos) => {
145
- return 'id:' + (pos + 1) + '\n' + i;
146
- }).join('\n---\n');
147
- out = (await chat(msg, 0, 0, {
148
- tools: {
149
- google_search: {}
150
- }
151
- }));
152
- ({
153
- // write '/tmp/fact.json',JSON.stringify out
154
- // out = JSON.parse read '/tmp/fact.json'
155
- content,
156
- groundingMetadata: {groundingChunks, groundingSupports}
157
- } = out);
158
- if (!groundingChunks) {
159
- return new Map();
160
- }
161
- content = content.parts[0].text;
162
- console.log(content);
163
- url_li = [];
164
- for (x of groundingChunks) {
165
- ({
166
- web: {uri}
167
- } = x);
168
- url_li.push(realUrl(uri));
169
- }
170
- url_li = (await Promise.all(url_li));
171
- for (i of groundingSupports) {
172
- i.groundingChunkIndices = urlLi(i.groundingChunkIndices, url_li);
173
- }
174
- map = new Map();
175
- ref = txtLi(addUrl(content, groundingSupports));
176
- for (i of ref) {
177
- console.log(i);
178
- if (!SHOW_KIND.includes((ref1 = i.失实度) != null ? ref1.split('[')[0] : void 0)) {
179
- continue;
180
- }
181
- li = map.get(i.id);
182
- if (!li) {
183
- li = [];
184
- map.set(i.id, li);
185
- }
186
- li.push(i);
187
- }
188
- return map;
189
- });
package/lib/fmtJson.js DELETED
@@ -1,19 +0,0 @@
1
- #!/usr/bin/env -S node --trace-uncaught --expose-gc --unhandled-rejections=strict --experimental-wasm-modules
2
- import fmtSeg from './fmtSeg.js';
3
-
4
- import partition from './partition.js';
5
-
6
- import RmCnSpace from '@3-/rm_cn_space';
7
-
8
- export default async(chat, txt) => {
9
- var pli;
10
- if (!txt) {
11
- return [];
12
- }
13
- txt = RmCnSpace(txt);
14
- pli = (await partition(chat, txt));
15
- return Promise.all(pli.map(async([title, li]) => {
16
- console.log('\n---\n→ ' + title + '\n' + li.join('\n') + '\n---\n');
17
- return [title, (await fmtSeg(chat, li.join('\n')))];
18
- }));
19
- };
@@ -1,58 +0,0 @@
1
- #!/usr/bin/env -S node --trace-uncaught --expose-gc --unhandled-rejections=strict --experimental-wasm-modules
2
- var check;
3
-
4
- import fmtJson from './fmtJson.js';
5
-
6
- import fmtJsonMd from './fmtJsonMd.js';
7
-
8
- import factCheck from './factCheck.js';
9
-
10
- import txtFmt from '@3-/txt_li/txtFmt.js';
11
-
12
- // @3-/read
13
- // @3-/write
14
- check = async(chat, json) => {
15
- var checked, j, k, li, n, tip, x, y, z, 答, 问, 问答;
16
- li = [];
17
- for (x of json) {
18
- ({问答} = x);
19
- for (y of 问答) {
20
- ({问, 答} = y);
21
- li.push(`问:${txtFmt(问)}\n答:${txtFmt(答)}`);
22
- }
23
- }
24
- checked = (await factCheck(chat, li));
25
- n = 0;
26
- for (z of json) {
27
- ({问答} = z);
28
- for (j of 问答) {
29
- li = checked.get(++n);
30
- if (li) {
31
- for (k of li) {
32
- if (k.失实度 === '严重失实') {
33
- tip = '❗ 失实:';
34
- } else {
35
- tip = '⚠️';
36
- }
37
- j.答 += `\n#### ${tip} ${k.标题}
38
-
39
- 观点: ${k.观点}
40
-
41
- 事实: ${k.事实}`;
42
- }
43
- }
44
- }
45
- }
46
- };
47
-
48
- export default async(chat, txt) => {
49
- var json_li;
50
- json_li = (await fmtJson(chat, txt));
51
- // write('/tmp/chat.json', JSON.stringify(json_li))
52
- // json_li = JSON.parse read('/tmp/chat.json')
53
- // await check(chat, json_li[0])
54
- await Promise.all(json_li.map((i) => {
55
- return check(chat, i);
56
- }));
57
- return fmtJsonMd(json_li);
58
- };
package/lib/package.json DELETED
@@ -1 +0,0 @@
1
- {"name":"@3-/aiapi","version":"0.1.75","repository":{"type":"git","url":"git+https://atomgit.com/i18n/lib.git"},"homepage":"https://atomgit.com/i18n/lib/tree/dev/aiapi","author":"i18n.site@gmail.com","license":"MulanPSL-2.0","exports":{".":"./lib.js","./*":"./*"},"files":["./*"],"devDependencies":{"@3-/read":"^0.1.4"},"scripts":{},"type":"module","dependencies":{"@3-/retry":"^0.0.2","@3-/rm_cn_space":"^0.1.1","@3-/sleep":"^0.0.4","@3-/txt_li":"^0.1.5","@3-/utf8":"^0.0.4","lodash-es":"^4.17.21"}}
File without changes
File without changes
File without changes
File without changes