@keo-ai/axiom 0.2.6 → 0.2.8

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 CHANGED
@@ -194,16 +194,21 @@ for await (const chunk of LLM.streamPredict({ model: 'qwen-max', prompt: '讲个
194
194
  |------|----------|-----------|------|
195
195
  | `qwen-max` | ❌ 不支持 | ✅ | **默认模型** |
196
196
  | `qwen3.7-max` | ✅ 映射支持 | ✅ | `low`/`medium`/`high` 映射为 `enable_thinking` |
197
+ | `qwen3.7-flash` | ✅ 映射支持 | ✅ | 同上 |
197
198
  | `qwen-plus` | ✅ 映射支持 | ✅ | 同上 |
198
199
  | `qwen-turbo` | ✅ 映射支持 | ✅ | 同上 |
199
- | `deepseek-v4-pro` | ✅ 原生支持 | ✅ | `low`/`medium`/`high` 直接传递 |
200
- | `deepseek-v4-flash` | ✅ 原生支持 | ✅ | 同上 |
201
- | `kimi-k2.6` | ✅ 原生支持 | ✅ | 同上 |
200
+ | `deepseek-v4-pro` | ✅ 映射支持 | ✅ | 同上(百炼走「混合思考模式」,由 `enable_thinking` 控制) |
201
+ | `deepseek-v4-flash` | ✅ 映射支持 | ✅ | 同上 |
202
+ | `kimi-k2.6` | ✅ 映射支持 | ✅ | `low`/`medium`/`high` 映射为 `extra_body.thinking.type` |
202
203
  | `qwq-plus` | ❌ 不支持 | ✅ | 固定推理行为,不可调节 |
203
204
  | `glm-5.1` | ❌ 不支持 | ❌ | 不支持推理参数,不支持 json 模式 |
204
205
  | `qwen-vl-plus` | ❌ 不支持 | ✅ | 视觉模型,不支持推理参数 |
205
206
 
206
- > 推理深度的支持方式由 Provider 内部维护。百炼 Provider 中,Qwen 系列通过 `extra_body.enable_thinking` 映射实现(`low` 关闭,`medium`/`high` 开启),DeepSeek / Kimi 则原生透传 `reasoning_effort`。
207
+ > 推理深度的支持方式由 Provider 内部维护。百炼 Provider 中:
208
+ > - Qwen 系列与 DeepSeek v4 系列均通过 `extra_body.enable_thinking` 映射实现(`low` 关闭,`medium`/`high` 开启);
209
+ > - Kimi 则通过 `extra_body.thinking.type` 映射(`low` 关闭,`medium`/`high` 开启)。
210
+ >
211
+ > 两种模式在百炼兼容接口下都退化为布尔开关,`medium` / `high` 之间的差异无法体现。
207
212
  >
208
213
  > 目前所有模型均路由到百炼 Provider。后续接入其他厂商时,通过 `MODEL_REGISTRY` 扩展映射即可。
209
214
 
@@ -13,7 +13,7 @@ exports.embed = embed;
13
13
  exports.embedBatch = embedBatch;
14
14
  const EMBEDDING_URL = 'https://dashscope.aliyuncs.com/compatible-mode/v1/embeddings';
15
15
  const EMBEDDING_MODEL = 'text-embedding-v4';
16
- const BATCH_SIZE_LIMIT = 25; // DashScope 兼容接口的单次上限
16
+ const BATCH_SIZE_LIMIT = 10; // DashScope 兼容接口的单次上限
17
17
  function getApiKey() {
18
18
  const apiKey = process.env.BAILIAN_API_KEY;
19
19
  if (!apiKey) {
@@ -34,7 +34,7 @@ export declare class EmbeddingSearch {
34
34
  /**
35
35
  * 批量获取文本向量。
36
36
  *
37
- * 调用百炼 embedding 接口,一次最多 25 条文本。
37
+ * 调用百炼 embedding 接口,一次最多 10 条文本。
38
38
  * 返回向量的顺序与输入顺序一致。
39
39
  *
40
40
  * @example
@@ -179,7 +179,7 @@ class EmbeddingSearch {
179
179
  /**
180
180
  * 批量获取文本向量。
181
181
  *
182
- * 调用百炼 embedding 接口,一次最多 25 条文本。
182
+ * 调用百炼 embedding 接口,一次最多 10 条文本。
183
183
  * 返回向量的顺序与输入顺序一致。
184
184
  *
185
185
  * @example
@@ -129,7 +129,7 @@ function createLLMCaller(options) {
129
129
  'Content-Type': 'application/json',
130
130
  Authorization: `Bearer ${options.apiKey}`,
131
131
  },
132
- body: JSON.stringify(body),
132
+ body: (0, llm_provider_1.serializeChatRequest)(body),
133
133
  }));
134
134
  }
135
135
  catch (cause) {
package/dist/index.d.ts CHANGED
@@ -37,7 +37,7 @@ export type { PredictConfig, PredictWithMessagesConfig } from './predict';
37
37
  * - `EmbeddingSearch.query()` — 文本 → embedding → pgvector 检索 → 可选 rerank
38
38
  * - `EmbeddingSearch.vectorSearch()` — 已有向量 → pgvector 近邻检索
39
39
  * - `EmbeddingSearch.embed()` — 单条文本转向量
40
- * - `EmbeddingSearch.batchEmbed()` — 批量文本转向量(单次最多 25 条)
40
+ * - `EmbeddingSearch.batchEmbed()` — 批量文本转向量(单次最多 10 条)
41
41
  */
42
42
  export { EmbeddingSearch } from './embedding_search';
43
43
  export type { EmbeddingSearchConfig, SearchResult } from './embedding_search';
package/dist/index.js CHANGED
@@ -73,7 +73,7 @@ Object.defineProperty(exports, "MODEL_REGISTRY", { enumerable: true, get: functi
73
73
  * - `EmbeddingSearch.query()` — 文本 → embedding → pgvector 检索 → 可选 rerank
74
74
  * - `EmbeddingSearch.vectorSearch()` — 已有向量 → pgvector 近邻检索
75
75
  * - `EmbeddingSearch.embed()` — 单条文本转向量
76
- * - `EmbeddingSearch.batchEmbed()` — 批量文本转向量(单次最多 25 条)
76
+ * - `EmbeddingSearch.batchEmbed()` — 批量文本转向量(单次最多 10 条)
77
77
  */
78
78
  var embedding_search_1 = require("./embedding_search");
79
79
  Object.defineProperty(exports, "EmbeddingSearch", { enumerable: true, get: function () { return embedding_search_1.EmbeddingSearch; } });
@@ -56,22 +56,21 @@ class BailianProvider {
56
56
  if (((_b = body.response_format) === null || _b === void 0 ? void 0 : _b.type) === 'json_object' && !caps.jsonMode) {
57
57
  throw new Error(`[adapt] Model "${body.model}" does not support response_format json_object`);
58
58
  }
59
- // 百炼平台:Qwen 系列通过 enable_thinking 实现 reasoning_effort
60
- // Kimi(Moonshot)通过 extra_body.thinking.type 实现(默认开启)
59
+ // 百炼平台:Qwen 系列与 DeepSeek v4 系列均为「混合思考模式」,
60
+ // 通过 extra_body.enable_thinking 控制思考开关(low 关闭,medium/high 开启);
61
+ // Kimi(Moonshot)则通过 extra_body.thinking.type 实现(默认开启)。
61
62
  if (body.reasoning_effort !== undefined) {
62
- if (['qwen-plus', 'qwen-turbo', 'qwen3.7-max'].includes(body.model)) {
63
+ if (['qwen-plus', 'qwen-turbo', 'qwen3.7-max', 'qwen3.7-flash', 'deepseek-v4-pro', 'deepseek-v4-flash'].includes(body.model)) {
63
64
  const { reasoning_effort } = body, rest = __rest(body, ["reasoning_effort"]);
64
65
  return Object.assign(Object.assign({}, rest), { extra_body: Object.assign(Object.assign({}, ((_c = rest.extra_body) !== null && _c !== void 0 ? _c : {})), { enable_thinking: reasoning_effort !== 'low' }) });
65
66
  }
66
67
  if (body.model === 'kimi-k2.6') {
67
68
  const { reasoning_effort } = body, rest = __rest(body, ["reasoning_effort"]);
68
- // Kimi 默认开启思考;只有 low 显式禁用,medium/high 走默认(不传 thinking 字段)
69
- if (reasoning_effort === 'low') {
70
- return Object.assign(Object.assign({}, rest), { extra_body: Object.assign(Object.assign({}, ((_d = rest.extra_body) !== null && _d !== void 0 ? _d : {})), { thinking: { type: 'disabled' } }) });
71
- }
72
- return rest;
69
+ // 百炼兼容模式下 Kimi 默认不输出 reasoning_content,
70
+ // 需要显式传 thinking.type:low 禁用,medium/high 显式开启
71
+ return Object.assign(Object.assign({}, rest), { extra_body: Object.assign(Object.assign({}, ((_d = rest.extra_body) !== null && _d !== void 0 ? _d : {})), { thinking: { type: reasoning_effort === 'low' ? 'disabled' : 'enabled' } }) });
73
72
  }
74
- // deepseek-v4-pro / deepseek-v4-flash 原生支持 reasoning_effort,直接传递
73
+ // 其它不支持 reasoning_effort 的模型会由前面的能力校验抛异常
75
74
  }
76
75
  return body;
77
76
  }
@@ -121,7 +120,7 @@ class BailianProvider {
121
120
  'Content-Type': 'application/json',
122
121
  Authorization: `Bearer ${this.config.apiKey}`,
123
122
  },
124
- body: JSON.stringify(body),
123
+ body: (0, index_1.serializeChatRequest)(body),
125
124
  }));
126
125
  }
127
126
  catch (cause) {
@@ -214,6 +213,7 @@ class BailianProvider {
214
213
  exports.BailianProvider = BailianProvider;
215
214
  BailianProvider.SUPPORTED_MODELS = new Set([
216
215
  'qwen3.7-max',
216
+ 'qwen3.7-flash',
217
217
  'qwen-plus',
218
218
  'qwen-turbo',
219
219
  'qwq-plus',
@@ -226,9 +226,12 @@ BailianProvider.SUPPORTED_MODELS = new Set([
226
226
  BailianProvider.MODEL_CAPABILITIES = {
227
227
  'qwen-max': { jsonMode: true, reasoningEffort: false },
228
228
  'qwen3.7-max': { jsonMode: true, reasoningEffort: true },
229
+ 'qwen3.7-flash': { jsonMode: true, reasoningEffort: true },
229
230
  'qwen-plus': { jsonMode: true, reasoningEffort: true },
230
231
  'qwen-turbo': { jsonMode: true, reasoningEffort: true },
231
232
  'qwq-plus': { jsonMode: true, reasoningEffort: false },
233
+ // DeepSeek v4 系列在百炼走「混合思考模式」:由 enable_thinking 控制开关,
234
+ // 通过 adaptRequest 映射为 extra_body.enable_thinking(与 Qwen 同一分支)。
232
235
  'deepseek-v4-pro': { jsonMode: true, reasoningEffort: true },
233
236
  'deepseek-v4-flash': { jsonMode: true, reasoningEffort: true },
234
237
  'kimi-k2.6': { jsonMode: true, reasoningEffort: true },
@@ -69,6 +69,12 @@ export interface OpenAIChatResponse {
69
69
  };
70
70
  model?: string;
71
71
  }
72
+ /**
73
+ * 序列化 chat completion 请求体。
74
+ * `extra_body` 是 OpenAI SDK 的客户端概念,在 HTTP 协议层面不存在,
75
+ * 必须将其内容展平到请求体顶层,否则服务端会忽略这些扩展参数。
76
+ */
77
+ export declare function serializeChatRequest(body: OpenAIChatRequest): string;
72
78
  /**
73
79
  * 发送 OpenAI 兼容的 chat completions 请求。
74
80
  * 只做 HTTP 层:构造请求、fetch、错误处理、基础解析。
@@ -12,9 +12,30 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
12
12
  step((generator = generator.apply(thisArg, _arguments || [])).next());
13
13
  });
14
14
  };
15
+ var __rest = (this && this.__rest) || function (s, e) {
16
+ var t = {};
17
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
18
+ t[p] = s[p];
19
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
20
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
21
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
22
+ t[p[i]] = s[p[i]];
23
+ }
24
+ return t;
25
+ };
15
26
  Object.defineProperty(exports, "__esModule", { value: true });
16
27
  exports.BailianProvider = exports.MODEL_REGISTRY = void 0;
28
+ exports.serializeChatRequest = serializeChatRequest;
17
29
  exports.callChatCompletions = callChatCompletions;
30
+ /**
31
+ * 序列化 chat completion 请求体。
32
+ * `extra_body` 是 OpenAI SDK 的客户端概念,在 HTTP 协议层面不存在,
33
+ * 必须将其内容展平到请求体顶层,否则服务端会忽略这些扩展参数。
34
+ */
35
+ function serializeChatRequest(body) {
36
+ const { extra_body } = body, rest = __rest(body, ["extra_body"]);
37
+ return JSON.stringify(Object.assign(Object.assign({}, rest), (extra_body !== null && extra_body !== void 0 ? extra_body : {})));
38
+ }
18
39
  /**
19
40
  * 发送 OpenAI 兼容的 chat completions 请求。
20
41
  * 只做 HTTP 层:构造请求、fetch、错误处理、基础解析。
@@ -32,7 +53,7 @@ function callChatCompletions(baseUrl_1, apiKey_1, body_1) {
32
53
  'Content-Type': 'application/json',
33
54
  Authorization: `Bearer ${apiKey}`,
34
55
  },
35
- body: JSON.stringify(body),
56
+ body: serializeChatRequest(body),
36
57
  });
37
58
  }
38
59
  catch (cause) {
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * 支持的模型枚举。项目层通过此枚举选择模型,Axiom 内部路由到对应 Provider。
3
3
  */
4
- export type Model = 'qwen3.7-max' | 'qwen-plus' | 'qwen-turbo' | 'qwq-plus' | 'deepseek-v4-pro' | 'deepseek-v4-flash' | 'kimi-k2.6' | 'glm-5.1' | 'qwen-vl-plus';
4
+ export type Model = 'qwen3.7-max' | 'qwen3.7-flash' | 'qwen-plus' | 'qwen-turbo' | 'qwq-plus' | 'deepseek-v4-pro' | 'deepseek-v4-flash' | 'kimi-k2.6' | 'glm-5.1' | 'qwen-vl-plus';
5
5
  /** 模型到 Provider 的映射配置 */
6
6
  export interface ModelConfig {
7
7
  readonly model: string;
@@ -16,7 +16,10 @@ export declare const MODEL_REGISTRY: Readonly<Record<Model, ReadonlyArray<ModelC
16
16
  export interface ModelCapabilities {
17
17
  /** 是否原生支持 response_format: { type: 'json_object' } */
18
18
  readonly jsonMode: boolean;
19
- /** 是否支持 reasoning_effort 参数 */
19
+ /**
20
+ * 是否支持调节推理深度。开启后由 Provider 的 `adaptRequest` 决定如何映射到底层字段
21
+ * (如 Qwen / DeepSeek → `extra_body.enable_thinking`、Kimi → `extra_body.thinking.type`)。
22
+ */
20
23
  readonly reasoningEffort: boolean;
21
24
  }
22
25
  /**
@@ -7,6 +7,7 @@ exports.MODEL_REGISTRY = void 0;
7
7
  */
8
8
  exports.MODEL_REGISTRY = {
9
9
  'qwen3.7-max': [{ model: 'qwen3.7-max', provider: 'bailian' }],
10
+ 'qwen3.7-flash': [{ model: 'qwen3.7-flash', provider: 'bailian' }],
10
11
  'qwen-plus': [{ model: 'qwen-plus', provider: 'bailian' }],
11
12
  'qwen-turbo': [{ model: 'qwen-turbo', provider: 'bailian' }],
12
13
  'qwq-plus': [{ model: 'qwq-plus', provider: 'bailian' }],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@keo-ai/axiom",
3
- "version": "0.2.6",
3
+ "version": "0.2.8",
4
4
  "description": "基于 LLM 的预测与推理库,支持多 Provider 切换",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -10,7 +10,9 @@
10
10
  "license": "MIT",
11
11
  "scripts": {
12
12
  "build": "tsc",
13
- "test": "vitest run --exclude '**/*.integration.test.ts'"
13
+ "typecheck": "tsc --noEmit",
14
+ "test": "vitest run --exclude '**/*.integration.test.ts'",
15
+ "test:integration": "vitest run --config vitest.integration.config.ts"
14
16
  },
15
17
  "dependencies": {
16
18
  "dotenv": "^17.4.2"