@mmteam/jsllm 0.1.6 → 0.1.11
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 +191 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -2,15 +2,204 @@
|
|
|
2
2
|
|
|
3
3
|
独立的 LLM 能力库:封装多供应商差异(OpenAI 兼容、Gemini)与会话执行(含工具循环/落盘)。
|
|
4
4
|
|
|
5
|
+
发布形态:
|
|
6
|
+
- 单文件运行时代码:`dist/index.cjs`(CommonJS,已 bundle 所有运行时依赖)
|
|
7
|
+
- 单文件类型声明:`dist/types.d.ts`
|
|
8
|
+
- 发布包零 dependencies(下游安装后无需额外安装 OpenAI/Gemini SDK 等依赖)
|
|
9
|
+
|
|
10
|
+
## 功能概览
|
|
11
|
+
- 统一供应商:OpenAI 兼容 / Gemini
|
|
12
|
+
- 统一会话:会话目录管理、消息落盘、历史恢复、usage 累计
|
|
13
|
+
- 流式输出:stdout 输出回答;stderr 输出诊断与 think/reasoning(若模型提供)
|
|
14
|
+
- 工具循环:内置 `shell` 工具(模型触发时在工作区执行命令,并回填输出)
|
|
15
|
+
|
|
5
16
|
## 安装
|
|
6
17
|
|
|
7
18
|
```bash
|
|
8
19
|
npm i @mmteam/jsllm
|
|
9
20
|
```
|
|
10
21
|
|
|
11
|
-
##
|
|
22
|
+
## 环境要求
|
|
23
|
+
- Node.js >= 20
|
|
24
|
+
|
|
25
|
+
## 快速开始
|
|
26
|
+
|
|
27
|
+
### CommonJS(推荐)
|
|
28
|
+
```js
|
|
29
|
+
const path = require("node:path");
|
|
30
|
+
const { chatInSession } = require("@mmteam/jsllm");
|
|
31
|
+
|
|
32
|
+
async function main() {
|
|
33
|
+
await chatInSession({
|
|
34
|
+
init: {
|
|
35
|
+
providerName: "openai",
|
|
36
|
+
apiType: "openai",
|
|
37
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
38
|
+
model: "gpt-4o-mini",
|
|
39
|
+
temperature: 0.7,
|
|
40
|
+
},
|
|
41
|
+
workspaceRoot: process.cwd(),
|
|
42
|
+
sessionRootDir: path.join(process.cwd(), ".magicai/chat-sessions"),
|
|
43
|
+
messageArg: "hello",
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
main().catch((err) => {
|
|
48
|
+
console.error(err);
|
|
49
|
+
process.exitCode = 1;
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
输入规则:
|
|
54
|
+
- 若提供 `messageArg`,使用其作为用户输入
|
|
55
|
+
- 否则当 stdin 非 TTY 时读取 stdin;两者都没有则报错
|
|
56
|
+
|
|
57
|
+
### ESM 项目中使用(可选)
|
|
58
|
+
本包对外导出为 CommonJS(`require`)。在纯 ESM 项目中可用 `createRequire` 引用:
|
|
59
|
+
```js
|
|
60
|
+
import { createRequire } from "node:module";
|
|
61
|
+
const require = createRequire(import.meta.url);
|
|
62
|
+
const { chatDirectText } = require("@mmteam/jsllm");
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## API
|
|
66
|
+
对外仅导出 2 个函数(以及必要类型):
|
|
67
|
+
|
|
68
|
+
详细参数、类型与中文说明:请参考 `node_modules/@mmteam/jsllm/dist/types.d.ts`(本仓库构建产物对应 `projects/jsllm/codex-zf/dist/types.d.ts`)。
|
|
69
|
+
|
|
70
|
+
### 如何选择?
|
|
71
|
+
| 能力 | `chatDirectText` | `chatInSession` |
|
|
72
|
+
|---|---|---|
|
|
73
|
+
| 目标 | 单轮生成(返回文本) | 会话引擎(落盘 + 工具循环 + 流式输出) |
|
|
74
|
+
| 输入 | 调用方提供 `messages` | `messageArg` 或 stdin;并自动加载会话历史 |
|
|
75
|
+
| 输出 | `Promise<string>` | stdout 流式输出;会话文件落盘;stderr 输出诊断/think |
|
|
76
|
+
| 工具 | 不启用、不执行 | 内置 `shell`(模型触发时执行并回填) |
|
|
77
|
+
| 适用场景 | 摘要/改写/分类等一次性生成;你自管存储 | CLI/交互式场景;需要可追溯、可续写会话 |
|
|
78
|
+
|
|
79
|
+
### `chatDirectText(init, messages): Promise<string>`
|
|
80
|
+
- 用途:不落盘、不启用工具的“单轮文本生成”,返回最终聚合文本
|
|
81
|
+
- 示例:
|
|
82
|
+
```js
|
|
83
|
+
const { chatDirectText } = require("@mmteam/jsllm");
|
|
84
|
+
const text = await chatDirectText(
|
|
85
|
+
{
|
|
86
|
+
providerName: "gemini",
|
|
87
|
+
apiType: "gemini",
|
|
88
|
+
apiKey: process.env.GEMINI_API_KEY,
|
|
89
|
+
model: "gemini-1.5-pro",
|
|
90
|
+
},
|
|
91
|
+
[
|
|
92
|
+
{ role: "user", content: "Summarize: ..." },
|
|
93
|
+
],
|
|
94
|
+
);
|
|
95
|
+
console.log(text);
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### `chatInSession(options): Promise<void>`
|
|
99
|
+
- 用途:执行一次“CLI 式会话主循环”(会话落盘 + 流式输出 + 工具循环)
|
|
100
|
+
- 重要参数:
|
|
101
|
+
- `workspaceRoot`:工作区根目录(用于解析 `public/agents`,以及工具执行 cwd)
|
|
102
|
+
- `sessionRootDir`:会话根目录(会在其下创建会话目录与 `latest` 软链)
|
|
103
|
+
- `systemPrompt`:支持内联文本或 `@` 引用文件/agent 名称(见下方说明)
|
|
104
|
+
- `consoleOutput`:是否写入 stdout/stderr(默认 `true`)
|
|
105
|
+
- `onEvent`:实时输出回调(区分正常回复 text 与 think,并携带与落盘一致的文件名/路径)
|
|
106
|
+
|
|
107
|
+
## 供应商与配置
|
|
108
|
+
|
|
109
|
+
### OpenAI 兼容(`apiType: "openai"`)
|
|
110
|
+
```js
|
|
111
|
+
init: {
|
|
112
|
+
providerName: "openai", // 或 dashscope / 自建网关等;qwen* 见下
|
|
113
|
+
apiType: "openai",
|
|
114
|
+
apiKey: "...",
|
|
115
|
+
baseUrl: "https://your-gateway.example.com", // 可选
|
|
116
|
+
model: "gpt-4o-mini",
|
|
117
|
+
temperature: 0.7,
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Gemini(`apiType: "gemini"`)
|
|
122
|
+
```js
|
|
123
|
+
init: {
|
|
124
|
+
providerName: "gemini",
|
|
125
|
+
apiType: "gemini",
|
|
126
|
+
apiKey: "...",
|
|
127
|
+
baseUrl: "https://generativelanguage.googleapis.com", // 可选;仅代理/国内环境需要
|
|
128
|
+
apiVersion: "v1beta", // 建议显式配置;预览模型推荐 v1beta
|
|
129
|
+
model: "gemini-1.5-pro",
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
- `baseUrl`:非必须;未配置时使用 SDK 默认地址
|
|
133
|
+
- `apiVersion`:建议显式配置;预览模型常用 `v1beta`
|
|
134
|
+
|
|
135
|
+
### qwen*(OpenAI 兼容扩展)
|
|
136
|
+
判断规则:`providerName` 以 `qwen` 前缀(不区分大小写)即视为 qwen 模式(如 `qwen1`、`qwen-local`)。
|
|
137
|
+
|
|
138
|
+
thinking 参数:
|
|
139
|
+
- 公共字段:`thinking.enabled`、`thinking.budgetTokens`
|
|
140
|
+
- qwen 私有字段:`qwen.enable_thinking`、`qwen.thinking_budget`(优先级高于公共字段)
|
|
141
|
+
|
|
142
|
+
示例:
|
|
143
|
+
```js
|
|
144
|
+
init: {
|
|
145
|
+
providerName: "qwen-local",
|
|
146
|
+
apiType: "openai",
|
|
147
|
+
apiKey: "...",
|
|
148
|
+
baseUrl: "http://localhost:8000/v1",
|
|
149
|
+
model: "qwen2.5",
|
|
150
|
+
thinking: { enabled: true, budgetTokens: 2048 },
|
|
151
|
+
qwen: { enable_thinking: true, thinking_budget: 2048 },
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## 会话落盘说明(`chatInSession`)
|
|
156
|
+
- 会话根目录:由 `sessionRootDir` 指定
|
|
157
|
+
- 会话目录:`YYYYMMDD_HHMMSS/`
|
|
158
|
+
- `latest`:会话根目录下的软链,指向最近一次有效会话目录
|
|
159
|
+
- `usage.json`:会话累计用量(当供应商返回 usage 时会自动累加)
|
|
160
|
+
- 消息文件:按序号落盘,支持恢复历史继续会话
|
|
161
|
+
- `.think`:当模型输出 reasoning/think 时,会额外落盘同名 `.think` 文件
|
|
162
|
+
|
|
163
|
+
## 实时回调(`chatInSession.onEvent`)
|
|
164
|
+
你可以通过 `onEvent` 在应用侧接收流式输出,并区分正常回复与 think(事件中携带与落盘一致的文件名):
|
|
165
|
+
```js
|
|
166
|
+
await chatInSession({
|
|
167
|
+
/* ... */,
|
|
168
|
+
consoleOutput: false,
|
|
169
|
+
onEvent(e) {
|
|
170
|
+
if (e.type === "assistant_text") {
|
|
171
|
+
// e.textSoFar:当前轮累计的“正常回复”
|
|
172
|
+
}
|
|
173
|
+
if (e.type === "assistant_think") {
|
|
174
|
+
// e.thinkSoFar:当前轮累计的 think/reasoning
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## 多轮会话(`chatInSession`)
|
|
181
|
+
`chatInSession` 的多轮能力通过“会话目录落盘 + 下次加载历史”实现:每次调用会读取目标会话目录的历史消息并继续追加写入。
|
|
182
|
+
|
|
183
|
+
- 默认续写上一会话(推荐):多次调用时保持相同的 `sessionRootDir`,且不传 `sessionArg`,库会自动复用 `latest` 指向的会话目录。
|
|
184
|
+
- 固定到指定会话:传入 `sessionArg: "my-session"`(相对 `sessionRootDir` 的相对子目录),每次调用都使用同一个值,即可稳定续写同一会话。
|
|
185
|
+
- systemPrompt 建议:同一会话通常只在“第一轮”设置 `systemPrompt`;后续轮次不再传(或改用 `sessionArg` 固定会话),避免触发创建新会话导致上下文断裂。
|
|
186
|
+
|
|
187
|
+
## systemPrompt / globalAgent(`chatInSession`)
|
|
188
|
+
- `systemPrompt` 支持两种形式:
|
|
189
|
+
- 内联文本:直接传字符串
|
|
190
|
+
- 引用文件/agent:以 `@` 开头,例如 `@公共智能体` 或 `@./path/to/prompt.txt`
|
|
191
|
+
- 当引用的是名称(非绝对路径且不以 `./` 开头)时,会在 `${workspaceRoot}/public/agents/` 下查找,并允许省略 `.agent.md` 扩展名
|
|
192
|
+
|
|
193
|
+
## 环境变量
|
|
194
|
+
- `MCHAT_REQUEST_TIMEOUT_MS`:OpenAI 兼容请求超时(毫秒)
|
|
195
|
+
- `MCHAT_DEBUG`:Gemini provider debug 输出(`true/1` 开启)
|
|
196
|
+
|
|
197
|
+
## 安全说明(工具)
|
|
198
|
+
`chatInSession` 内置 `shell` 工具:当模型触发工具调用时,会在 `workspaceRoot` 下通过 `bash -lc` 执行命令并回填输出。请仅在可信环境中使用,并确保运行账号权限可控。
|
|
199
|
+
|
|
200
|
+
## 开发
|
|
201
|
+
> 下述为仓库开发者使用;下游项目不需要执行 build。
|
|
12
202
|
|
|
13
203
|
```bash
|
|
14
204
|
npm run build
|
|
15
205
|
```
|
|
16
|
-
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mmteam/jsllm",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.11",
|
|
4
4
|
"description": "MM Team LLM library (providers + chat/session runner)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
7
|
-
"types": "./dist/
|
|
7
|
+
"types": "./dist/types.d.ts",
|
|
8
8
|
"exports": {
|
|
9
9
|
".": {
|
|
10
|
-
"types": "./dist/
|
|
10
|
+
"types": "./dist/types.d.ts",
|
|
11
11
|
"require": "./dist/index.cjs"
|
|
12
12
|
}
|
|
13
13
|
},
|