@keo-ai/axiom 0.1.3 → 0.1.5
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 +402 -2
- package/dist/embedding_search/enums.d.ts +6 -0
- package/dist/embedding_search/enums.js +105 -0
- package/dist/embedding_search/index.js +10 -3
- package/dist/embedding_search/types.d.ts +1 -0
- package/dist/function_call_loop/harness.d.ts +34 -0
- package/dist/function_call_loop/harness.js +48 -0
- package/dist/function_call_loop/index.d.ts +14 -0
- package/dist/function_call_loop/index.js +17 -0
- package/dist/function_call_loop/loop.d.ts +2 -0
- package/dist/function_call_loop/loop.js +438 -0
- package/dist/function_call_loop/provider.d.ts +19 -0
- package/dist/function_call_loop/provider.js +73 -0
- package/dist/function_call_loop/types.d.ts +206 -0
- package/dist/function_call_loop/types.js +2 -0
- package/dist/index.d.ts +6 -3
- package/dist/index.js +39 -4
- package/dist/llm_provider/bailian.d.ts +28 -0
- package/dist/llm_provider/bailian.js +174 -0
- package/dist/llm_provider/index.d.ts +73 -0
- package/dist/llm_provider/index.js +62 -0
- package/dist/llm_provider/llm.d.ts +32 -0
- package/dist/llm_provider/llm.js +2 -0
- package/dist/llm_provider/models.d.ts +14 -0
- package/dist/llm_provider/models.js +17 -0
- package/dist/llm_provider/types.d.ts +51 -0
- package/dist/llm_provider/types.js +2 -0
- package/dist/predict/config.d.ts +2 -2
- package/dist/predict/index.d.ts +6 -5
- package/dist/predict/index.js +2 -2
- package/dist/predict/llm.d.ts +3 -33
- package/dist/predict/llm.js +1 -1
- package/dist/predict/models.d.ts +2 -14
- package/dist/predict/models.js +2 -14
- package/dist/predict/predict.d.ts +1 -1
- package/dist/predict/predict.js +1 -1
- package/dist/predict/types.d.ts +1 -51
- package/package.json +1 -1
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM 对话消息。支持 system、user、assistant、tool 四种角色。
|
|
3
|
+
* assistant 角色可携带 tool_calls;tool 角色需携带 tool_call_id。
|
|
4
|
+
*/
|
|
5
|
+
export interface Message {
|
|
6
|
+
readonly role: 'system' | 'user' | 'assistant' | 'tool';
|
|
7
|
+
readonly content: string;
|
|
8
|
+
readonly tool_calls?: ReadonlyArray<ToolCall>;
|
|
9
|
+
readonly tool_call_id?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* LLM 返回的工具调用。
|
|
13
|
+
*/
|
|
14
|
+
export interface ToolCall {
|
|
15
|
+
readonly id: string;
|
|
16
|
+
readonly type: 'function';
|
|
17
|
+
readonly function: {
|
|
18
|
+
readonly name: string;
|
|
19
|
+
readonly arguments: string;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* 暴露给 LLM 的工具定义。
|
|
24
|
+
*/
|
|
25
|
+
export interface ToolDefinition {
|
|
26
|
+
readonly type: 'function';
|
|
27
|
+
readonly function: {
|
|
28
|
+
readonly name: string;
|
|
29
|
+
readonly description: string;
|
|
30
|
+
readonly parameters: unknown;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Harness 记录的执行状态。
|
|
35
|
+
*/
|
|
36
|
+
export type HarnessRecordStatus = 'pending' | 'success' | 'error' | 'timeout' | 'cancelled';
|
|
37
|
+
/**
|
|
38
|
+
* 单条执行历史记录。
|
|
39
|
+
*/
|
|
40
|
+
export interface HarnessRecord {
|
|
41
|
+
readonly id: string;
|
|
42
|
+
readonly turn: number;
|
|
43
|
+
readonly globalIndex: number;
|
|
44
|
+
readonly toolName: string;
|
|
45
|
+
readonly args: unknown;
|
|
46
|
+
readonly rawArgs: string;
|
|
47
|
+
readonly status: HarnessRecordStatus;
|
|
48
|
+
readonly result?: unknown;
|
|
49
|
+
readonly error?: string;
|
|
50
|
+
readonly startedAt: number;
|
|
51
|
+
readonly durationMs: number;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* 执行前事件。
|
|
55
|
+
*/
|
|
56
|
+
export interface ToolExecutionStartEvent {
|
|
57
|
+
readonly type: 'execution:start';
|
|
58
|
+
readonly callId: string;
|
|
59
|
+
readonly toolName: string;
|
|
60
|
+
readonly args: unknown;
|
|
61
|
+
readonly turn: number;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 执行后事件(同时携带结果)。
|
|
65
|
+
*/
|
|
66
|
+
export interface ToolExecutionEndEvent {
|
|
67
|
+
readonly type: 'execution:end';
|
|
68
|
+
readonly callId: string;
|
|
69
|
+
readonly toolName: string;
|
|
70
|
+
readonly status: HarnessRecordStatus;
|
|
71
|
+
readonly durationMs: number;
|
|
72
|
+
readonly result?: unknown;
|
|
73
|
+
readonly error?: string;
|
|
74
|
+
readonly turn: number;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Loop 生命周期事件。
|
|
78
|
+
*/
|
|
79
|
+
export type LoopEvent = ToolExecutionStartEvent | ToolExecutionEndEvent;
|
|
80
|
+
/**
|
|
81
|
+
* Tool 发现函数的返回结果。
|
|
82
|
+
*/
|
|
83
|
+
export interface ToolDiscoverResult {
|
|
84
|
+
readonly name: string;
|
|
85
|
+
readonly description: string;
|
|
86
|
+
readonly parameters: unknown;
|
|
87
|
+
readonly visible: boolean;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Tool 执行上下文。
|
|
91
|
+
*/
|
|
92
|
+
export interface ToolExecuteContext {
|
|
93
|
+
readonly harness: ReadonlyArray<HarnessRecord>;
|
|
94
|
+
readonly turn: number;
|
|
95
|
+
readonly metadata: unknown;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Tool 审批配置。
|
|
99
|
+
* 当 tool 被调用时,先执行 createTicket 生成审批单,暂停 Loop 等待外部审批。
|
|
100
|
+
* createTicket 可通过 context.metadata 访问 LoopConfig 传入的 metadata,用于携带业务上下文(如用户ID、会话ID等)。
|
|
101
|
+
* 审批通过后恢复执行时,应通过某种方式(如 createTicket 内部查库)让 Loop 直接执行,无需去掉 approval 配置。
|
|
102
|
+
*/
|
|
103
|
+
export interface ApprovalConfig {
|
|
104
|
+
readonly createTicket: (args: unknown, context: ToolExecuteContext) => Promise<{
|
|
105
|
+
ticketId: string;
|
|
106
|
+
approved?: boolean;
|
|
107
|
+
}>;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* 注册到 Loop 中的 Tool。
|
|
111
|
+
*/
|
|
112
|
+
export interface Tool {
|
|
113
|
+
readonly name: string;
|
|
114
|
+
readonly description: string;
|
|
115
|
+
readonly parameters: unknown;
|
|
116
|
+
readonly discover?: (harness: ReadonlyArray<HarnessRecord>, metadata: unknown) => ToolDiscoverResult | Promise<ToolDiscoverResult>;
|
|
117
|
+
readonly execute: (args: unknown, context: ToolExecuteContext) => unknown | Promise<unknown>;
|
|
118
|
+
readonly approval?: ApprovalConfig;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Turn Policy 决策结果。
|
|
122
|
+
*/
|
|
123
|
+
export interface TurnPolicyResult {
|
|
124
|
+
/** 继续执行前作为 system 消息注入 */
|
|
125
|
+
readonly injectMessage?: string;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* 全局轮次策略。
|
|
129
|
+
*/
|
|
130
|
+
export type TurnPolicy = (harness: ReadonlyArray<HarnessRecord>, turn: number, metadata: unknown) => TurnPolicyResult | Promise<TurnPolicyResult>;
|
|
131
|
+
/**
|
|
132
|
+
* 上下文压缩配置。
|
|
133
|
+
*/
|
|
134
|
+
export interface CompactConfig {
|
|
135
|
+
readonly keepRounds: number;
|
|
136
|
+
readonly compress: (messages: ReadonlyArray<ReadonlyArray<Message>>) => Message[] | Promise<Message[]>;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* LLM 调用可选参数。
|
|
140
|
+
*/
|
|
141
|
+
export interface LLMCallOptions {
|
|
142
|
+
readonly model?: string;
|
|
143
|
+
readonly temperature?: number;
|
|
144
|
+
readonly maxTokens?: number;
|
|
145
|
+
readonly topP?: number;
|
|
146
|
+
readonly reasoningEffort?: 'low' | 'medium' | 'high';
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* LLM 调用接口。由外部注入,Loop 内部不绑定具体 Provider。
|
|
150
|
+
*/
|
|
151
|
+
export interface LLMCaller {
|
|
152
|
+
readonly call: (messages: ReadonlyArray<Message>, tools: ReadonlyArray<ToolDefinition>, options?: LLMCallOptions) => Promise<{
|
|
153
|
+
readonly content: string | null;
|
|
154
|
+
readonly tool_calls?: ReadonlyArray<ToolCall>;
|
|
155
|
+
}>;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Loop 配置。
|
|
159
|
+
*/
|
|
160
|
+
export interface LoopConfig {
|
|
161
|
+
/** 初始消息列表,直接作为对话起点 */
|
|
162
|
+
readonly messages: ReadonlyArray<Message>;
|
|
163
|
+
readonly tools: ReadonlyArray<Tool>;
|
|
164
|
+
readonly llmCaller?: LLMCaller;
|
|
165
|
+
readonly maxTurns?: number;
|
|
166
|
+
readonly turnPolicy?: TurnPolicy;
|
|
167
|
+
readonly compact?: CompactConfig;
|
|
168
|
+
readonly metadata?: unknown;
|
|
169
|
+
/** 告警文本:当 turnPolicy 未自定义且当前轮次等于 maxTurns - 1 时塞入 Messages */
|
|
170
|
+
readonly warningMessage?: string;
|
|
171
|
+
/** 终止文本:当 turnPolicy 未自定义且当前轮次等于 maxTurns 时塞入 Messages */
|
|
172
|
+
readonly terminateMessage?: string;
|
|
173
|
+
/** 事件监听器 */
|
|
174
|
+
readonly onEvent?: (event: LoopEvent) => void | Promise<void>;
|
|
175
|
+
/** 取消信号 */
|
|
176
|
+
readonly signal?: AbortSignal;
|
|
177
|
+
/** 模型名称。未设置时从环境变量或 Provider 默认值读取 */
|
|
178
|
+
readonly model?: import('../llm_provider/models').Model;
|
|
179
|
+
/** 采样温度,范围 0~2 */
|
|
180
|
+
readonly temperature?: number;
|
|
181
|
+
/** 单次 LLM 调用的最大输出 token 数 */
|
|
182
|
+
readonly maxTokens?: number;
|
|
183
|
+
/** 核采样概率阈值,范围 0~1 */
|
|
184
|
+
readonly topP?: number;
|
|
185
|
+
/** 推理深度。仅部分模型支持 */
|
|
186
|
+
readonly reasoningEffort?: 'low' | 'medium' | 'high';
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* 待审批信息。
|
|
190
|
+
*/
|
|
191
|
+
export interface PendingApprovalInfo {
|
|
192
|
+
readonly ticketId: string;
|
|
193
|
+
readonly toolName: string;
|
|
194
|
+
readonly args: unknown;
|
|
195
|
+
readonly callId: string;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Loop 执行结果。
|
|
199
|
+
*/
|
|
200
|
+
export interface LoopResult {
|
|
201
|
+
readonly messages: Message[];
|
|
202
|
+
readonly harness: ReadonlyArray<HarnessRecord>;
|
|
203
|
+
readonly finalContent: string | null;
|
|
204
|
+
readonly turns: number;
|
|
205
|
+
readonly pendingApproval?: PendingApprovalInfo;
|
|
206
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -26,9 +26,12 @@ export type { LLMProvider, PredictorOptions } from './predict';
|
|
|
26
26
|
export { Predictor } from './predict';
|
|
27
27
|
/** 百炼 Provider 实现 */
|
|
28
28
|
export { BailianProvider } from './predict';
|
|
29
|
-
/**
|
|
30
|
-
export { MODEL_REGISTRY } from './
|
|
31
|
-
export type { Model
|
|
29
|
+
/** 模型注册表与枚举,定义模型与 Provider 的映射关系 */
|
|
30
|
+
export { MODEL_REGISTRY } from './llm_provider';
|
|
31
|
+
export type { Model } from './llm_provider';
|
|
32
|
+
export type { PredictConfig, PredictWithMessagesConfig } from './predict';
|
|
32
33
|
/** 向量检索(Embedding + pgvector + Rerank) */
|
|
33
34
|
export { EmbeddingSearch, embed } from './embedding_search';
|
|
34
35
|
export type { EmbeddingSearchConfig, SearchResult } from './embedding_search';
|
|
36
|
+
/** Function Call Loop */
|
|
37
|
+
export * as FunctionCallLoop from './function_call_loop';
|
package/dist/index.js
CHANGED
|
@@ -19,8 +19,41 @@
|
|
|
19
19
|
*
|
|
20
20
|
* @packageDocumentation
|
|
21
21
|
*/
|
|
22
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
23
|
+
if (k2 === undefined) k2 = k;
|
|
24
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
25
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
26
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
27
|
+
}
|
|
28
|
+
Object.defineProperty(o, k2, desc);
|
|
29
|
+
}) : (function(o, m, k, k2) {
|
|
30
|
+
if (k2 === undefined) k2 = k;
|
|
31
|
+
o[k2] = m[k];
|
|
32
|
+
}));
|
|
33
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
34
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
35
|
+
}) : function(o, v) {
|
|
36
|
+
o["default"] = v;
|
|
37
|
+
});
|
|
38
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
39
|
+
var ownKeys = function(o) {
|
|
40
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
41
|
+
var ar = [];
|
|
42
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
43
|
+
return ar;
|
|
44
|
+
};
|
|
45
|
+
return ownKeys(o);
|
|
46
|
+
};
|
|
47
|
+
return function (mod) {
|
|
48
|
+
if (mod && mod.__esModule) return mod;
|
|
49
|
+
var result = {};
|
|
50
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
51
|
+
__setModuleDefault(result, mod);
|
|
52
|
+
return result;
|
|
53
|
+
};
|
|
54
|
+
})();
|
|
22
55
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
-
exports.embed = exports.EmbeddingSearch = exports.MODEL_REGISTRY = exports.BailianProvider = exports.Predictor = exports.LLM = void 0;
|
|
56
|
+
exports.FunctionCallLoop = exports.embed = exports.EmbeddingSearch = exports.MODEL_REGISTRY = exports.BailianProvider = exports.Predictor = exports.LLM = void 0;
|
|
24
57
|
/** LLM 静态入口类,封装 Provider 连接、故障转移和返回解析 */
|
|
25
58
|
var predict_1 = require("./predict");
|
|
26
59
|
Object.defineProperty(exports, "LLM", { enumerable: true, get: function () { return predict_1.LLM; } });
|
|
@@ -30,10 +63,12 @@ Object.defineProperty(exports, "Predictor", { enumerable: true, get: function ()
|
|
|
30
63
|
/** 百炼 Provider 实现 */
|
|
31
64
|
var predict_3 = require("./predict");
|
|
32
65
|
Object.defineProperty(exports, "BailianProvider", { enumerable: true, get: function () { return predict_3.BailianProvider; } });
|
|
33
|
-
/**
|
|
34
|
-
var
|
|
35
|
-
Object.defineProperty(exports, "MODEL_REGISTRY", { enumerable: true, get: function () { return
|
|
66
|
+
/** 模型注册表与枚举,定义模型与 Provider 的映射关系 */
|
|
67
|
+
var llm_provider_1 = require("./llm_provider");
|
|
68
|
+
Object.defineProperty(exports, "MODEL_REGISTRY", { enumerable: true, get: function () { return llm_provider_1.MODEL_REGISTRY; } });
|
|
36
69
|
/** 向量检索(Embedding + pgvector + Rerank) */
|
|
37
70
|
var embedding_search_1 = require("./embedding_search");
|
|
38
71
|
Object.defineProperty(exports, "EmbeddingSearch", { enumerable: true, get: function () { return embedding_search_1.EmbeddingSearch; } });
|
|
39
72
|
Object.defineProperty(exports, "embed", { enumerable: true, get: function () { return embedding_search_1.embed; } });
|
|
73
|
+
/** Function Call Loop */
|
|
74
|
+
exports.FunctionCallLoop = __importStar(require("./function_call_loop"));
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { LLMProvider } from './llm';
|
|
2
|
+
import type { LLMRequest, LLMResponse, ProviderConfig, StreamChunk } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* 阿里云百炼(兼容 OpenAI 协议)Provider 实现。
|
|
5
|
+
* 支持非流式调用和流式 SSE 输出。
|
|
6
|
+
*/
|
|
7
|
+
export declare class BailianProvider implements LLMProvider {
|
|
8
|
+
readonly config: ProviderConfig;
|
|
9
|
+
readonly name = "bailian";
|
|
10
|
+
private static readonly SUPPORTED_MODELS;
|
|
11
|
+
constructor(config: ProviderConfig);
|
|
12
|
+
supports(model: string): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* 发送非流式 chat completion 请求到百炼服务。
|
|
15
|
+
* @param request - 标准化 LLM 请求
|
|
16
|
+
* @returns 解析后的模型响应(含 content、usage、model)
|
|
17
|
+
* @throws Error - 网络异常时抛 `[bailian] ...`;HTTP 非 2xx 时抛 `[bailian] HTTP {status}: ...`
|
|
18
|
+
*/
|
|
19
|
+
generate(request: LLMRequest): Promise<LLMResponse>;
|
|
20
|
+
/**
|
|
21
|
+
* 发送流式 chat completion 请求,解析 SSE 响应逐块返回。
|
|
22
|
+
* @param request - 标准化 LLM 请求
|
|
23
|
+
* @yields 内容片段(`content`)或结束标记(`finish`)
|
|
24
|
+
* @throws Error - 网络异常或 HTTP 错误时抛出
|
|
25
|
+
*/
|
|
26
|
+
stream(request: LLMRequest): AsyncGenerator<StreamChunk, void, unknown>;
|
|
27
|
+
private buildRequestBody;
|
|
28
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
|
|
12
|
+
var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
|
|
13
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
14
|
+
var g = generator.apply(thisArg, _arguments || []), i, q = [];
|
|
15
|
+
return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
|
|
16
|
+
function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
|
|
17
|
+
function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
|
|
18
|
+
function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
|
|
19
|
+
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
|
|
20
|
+
function fulfill(value) { resume("next", value); }
|
|
21
|
+
function reject(value) { resume("throw", value); }
|
|
22
|
+
function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
|
|
23
|
+
};
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.BailianProvider = void 0;
|
|
26
|
+
const index_1 = require("./index");
|
|
27
|
+
/**
|
|
28
|
+
* 阿里云百炼(兼容 OpenAI 协议)Provider 实现。
|
|
29
|
+
* 支持非流式调用和流式 SSE 输出。
|
|
30
|
+
*/
|
|
31
|
+
class BailianProvider {
|
|
32
|
+
constructor(config) {
|
|
33
|
+
this.config = config;
|
|
34
|
+
this.name = 'bailian';
|
|
35
|
+
}
|
|
36
|
+
supports(model) {
|
|
37
|
+
return BailianProvider.SUPPORTED_MODELS.has(model);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* 发送非流式 chat completion 请求到百炼服务。
|
|
41
|
+
* @param request - 标准化 LLM 请求
|
|
42
|
+
* @returns 解析后的模型响应(含 content、usage、model)
|
|
43
|
+
* @throws Error - 网络异常时抛 `[bailian] ...`;HTTP 非 2xx 时抛 `[bailian] HTTP {status}: ...`
|
|
44
|
+
*/
|
|
45
|
+
generate(request) {
|
|
46
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
47
|
+
var _a;
|
|
48
|
+
const body = this.buildRequestBody(request);
|
|
49
|
+
const data = yield (0, index_1.callChatCompletions)(this.config.baseUrl, this.config.apiKey, Object.assign(Object.assign({}, body), { stream: false }), this.name);
|
|
50
|
+
const choice = data.choices[0];
|
|
51
|
+
return {
|
|
52
|
+
content: choice.message.content,
|
|
53
|
+
usage: data.usage
|
|
54
|
+
? {
|
|
55
|
+
promptTokens: data.usage.prompt_tokens,
|
|
56
|
+
completionTokens: data.usage.completion_tokens,
|
|
57
|
+
totalTokens: data.usage.total_tokens,
|
|
58
|
+
}
|
|
59
|
+
: undefined,
|
|
60
|
+
model: (_a = data.model) !== null && _a !== void 0 ? _a : body.model,
|
|
61
|
+
};
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 发送流式 chat completion 请求,解析 SSE 响应逐块返回。
|
|
66
|
+
* @param request - 标准化 LLM 请求
|
|
67
|
+
* @yields 内容片段(`content`)或结束标记(`finish`)
|
|
68
|
+
* @throws Error - 网络异常或 HTTP 错误时抛出
|
|
69
|
+
*/
|
|
70
|
+
stream(request) {
|
|
71
|
+
return __asyncGenerator(this, arguments, function* stream_1() {
|
|
72
|
+
var _a, _b;
|
|
73
|
+
const url = `${this.config.baseUrl}/chat/completions`;
|
|
74
|
+
const body = this.buildRequestBody(request);
|
|
75
|
+
let response;
|
|
76
|
+
try {
|
|
77
|
+
response = yield __await(fetch(url, {
|
|
78
|
+
method: 'POST',
|
|
79
|
+
headers: {
|
|
80
|
+
'Content-Type': 'application/json',
|
|
81
|
+
Authorization: `Bearer ${this.config.apiKey}`,
|
|
82
|
+
},
|
|
83
|
+
body: JSON.stringify(Object.assign(Object.assign({}, body), { stream: true })),
|
|
84
|
+
}));
|
|
85
|
+
}
|
|
86
|
+
catch (cause) {
|
|
87
|
+
throw new Error(`[${this.name}] ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
88
|
+
}
|
|
89
|
+
if (!response.ok) {
|
|
90
|
+
const text = yield __await(response.text());
|
|
91
|
+
throw new Error(`[${this.name}] HTTP ${response.status}: ${text}`);
|
|
92
|
+
}
|
|
93
|
+
if (!response.body) {
|
|
94
|
+
throw new Error(`[${this.name}] Response body is null`);
|
|
95
|
+
}
|
|
96
|
+
const reader = response.body.getReader();
|
|
97
|
+
const decoder = new TextDecoder();
|
|
98
|
+
let buffer = '';
|
|
99
|
+
try {
|
|
100
|
+
while (true) {
|
|
101
|
+
const { done, value } = yield __await(reader.read());
|
|
102
|
+
if (done)
|
|
103
|
+
break;
|
|
104
|
+
buffer += decoder.decode(value, { stream: true });
|
|
105
|
+
const lines = buffer.split('\n');
|
|
106
|
+
buffer = (_a = lines.pop()) !== null && _a !== void 0 ? _a : '';
|
|
107
|
+
for (const line of lines) {
|
|
108
|
+
const trimmed = line.trim();
|
|
109
|
+
if (!trimmed || !trimmed.startsWith('data: '))
|
|
110
|
+
continue;
|
|
111
|
+
const data = trimmed.slice(6);
|
|
112
|
+
if (data === '[DONE]')
|
|
113
|
+
continue;
|
|
114
|
+
let parsed;
|
|
115
|
+
try {
|
|
116
|
+
parsed = JSON.parse(data);
|
|
117
|
+
}
|
|
118
|
+
catch (_c) {
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
const choice = (_b = parsed.choices) === null || _b === void 0 ? void 0 : _b[0];
|
|
122
|
+
if (!choice)
|
|
123
|
+
continue;
|
|
124
|
+
const delta = choice.delta;
|
|
125
|
+
if (delta.content) {
|
|
126
|
+
yield yield __await({ type: 'content', delta: delta.content });
|
|
127
|
+
}
|
|
128
|
+
if (choice.finish_reason && parsed.usage) {
|
|
129
|
+
yield yield __await({
|
|
130
|
+
type: 'finish',
|
|
131
|
+
usage: {
|
|
132
|
+
promptTokens: parsed.usage.prompt_tokens,
|
|
133
|
+
completionTokens: parsed.usage.completion_tokens,
|
|
134
|
+
totalTokens: parsed.usage.total_tokens,
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
yield yield __await({ type: 'finish' });
|
|
141
|
+
}
|
|
142
|
+
finally {
|
|
143
|
+
reader.releaseLock();
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
buildRequestBody(request) {
|
|
148
|
+
var _a;
|
|
149
|
+
return {
|
|
150
|
+
model: (_a = request.model) !== null && _a !== void 0 ? _a : this.config.defaultModel,
|
|
151
|
+
messages: request.messages.map((m) => ({
|
|
152
|
+
role: m.role,
|
|
153
|
+
content: m.content,
|
|
154
|
+
})),
|
|
155
|
+
temperature: request.temperature,
|
|
156
|
+
max_tokens: request.maxTokens,
|
|
157
|
+
top_p: request.topP,
|
|
158
|
+
response_format: request.responseFormat
|
|
159
|
+
? { type: request.responseFormat === 'json' ? 'json_object' : 'text' }
|
|
160
|
+
: undefined,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
exports.BailianProvider = BailianProvider;
|
|
165
|
+
BailianProvider.SUPPORTED_MODELS = new Set([
|
|
166
|
+
'qwen3.7-max',
|
|
167
|
+
'qwen-plus',
|
|
168
|
+
'qwen-turbo',
|
|
169
|
+
'qwq-plus',
|
|
170
|
+
'deepseek-v4-pro',
|
|
171
|
+
'deepseek-v4-flash',
|
|
172
|
+
'kimi-k2.6',
|
|
173
|
+
'qwen-vl-plus',
|
|
174
|
+
]);
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM Provider 底层 HTTP 调用层。
|
|
3
|
+
* Predict 模块和 Function Call Loop 模块共用,只负责纯粹的请求/响应/错误处理。
|
|
4
|
+
*/
|
|
5
|
+
export interface OpenAIChatMessage {
|
|
6
|
+
role: string;
|
|
7
|
+
content: string | null;
|
|
8
|
+
tool_calls?: Array<{
|
|
9
|
+
id: string;
|
|
10
|
+
type: 'function';
|
|
11
|
+
function: {
|
|
12
|
+
name: string;
|
|
13
|
+
arguments: string;
|
|
14
|
+
};
|
|
15
|
+
}>;
|
|
16
|
+
tool_call_id?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface OpenAIChatTool {
|
|
19
|
+
type: 'function';
|
|
20
|
+
function: {
|
|
21
|
+
name: string;
|
|
22
|
+
description: string;
|
|
23
|
+
parameters: unknown;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export interface OpenAIChatRequest {
|
|
27
|
+
model: string;
|
|
28
|
+
messages: OpenAIChatMessage[];
|
|
29
|
+
temperature?: number;
|
|
30
|
+
max_tokens?: number;
|
|
31
|
+
top_p?: number;
|
|
32
|
+
tools?: OpenAIChatTool[];
|
|
33
|
+
response_format?: {
|
|
34
|
+
type: 'text' | 'json_object';
|
|
35
|
+
};
|
|
36
|
+
stream?: boolean;
|
|
37
|
+
}
|
|
38
|
+
export interface OpenAIChatResponse {
|
|
39
|
+
choices: Array<{
|
|
40
|
+
message: {
|
|
41
|
+
content: string | null;
|
|
42
|
+
tool_calls?: Array<{
|
|
43
|
+
id: string;
|
|
44
|
+
type: 'function';
|
|
45
|
+
function: {
|
|
46
|
+
name: string;
|
|
47
|
+
arguments: string;
|
|
48
|
+
};
|
|
49
|
+
}>;
|
|
50
|
+
};
|
|
51
|
+
finish_reason: string | null;
|
|
52
|
+
}>;
|
|
53
|
+
usage?: {
|
|
54
|
+
prompt_tokens: number;
|
|
55
|
+
completion_tokens: number;
|
|
56
|
+
total_tokens: number;
|
|
57
|
+
};
|
|
58
|
+
model?: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* 发送 OpenAI 兼容的 chat completions 请求。
|
|
62
|
+
* 只做 HTTP 层:构造请求、fetch、错误处理、基础解析。
|
|
63
|
+
* 业务层(请求体组装、结果转换)由调用方负责。
|
|
64
|
+
*/
|
|
65
|
+
export declare function callChatCompletions(baseUrl: string, apiKey: string, body: OpenAIChatRequest, errorPrefix?: string): Promise<OpenAIChatResponse>;
|
|
66
|
+
/** 模型枚举与注册表 */
|
|
67
|
+
export type { Model, ModelConfig } from './models';
|
|
68
|
+
export { MODEL_REGISTRY } from './models';
|
|
69
|
+
/** 标准化类型 */
|
|
70
|
+
export type { Message, LLMRequest, LLMResponse, ProviderConfig, StreamChunk } from './types';
|
|
71
|
+
/** Provider 接口与实现 */
|
|
72
|
+
export type { LLMProvider } from './llm';
|
|
73
|
+
export { BailianProvider } from './bailian';
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* LLM Provider 底层 HTTP 调用层。
|
|
4
|
+
* Predict 模块和 Function Call Loop 模块共用,只负责纯粹的请求/响应/错误处理。
|
|
5
|
+
*/
|
|
6
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
7
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
8
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
9
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
10
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
11
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
12
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.BailianProvider = exports.MODEL_REGISTRY = void 0;
|
|
17
|
+
exports.callChatCompletions = callChatCompletions;
|
|
18
|
+
/**
|
|
19
|
+
* 发送 OpenAI 兼容的 chat completions 请求。
|
|
20
|
+
* 只做 HTTP 层:构造请求、fetch、错误处理、基础解析。
|
|
21
|
+
* 业务层(请求体组装、结果转换)由调用方负责。
|
|
22
|
+
*/
|
|
23
|
+
function callChatCompletions(baseUrl_1, apiKey_1, body_1) {
|
|
24
|
+
return __awaiter(this, arguments, void 0, function* (baseUrl, apiKey, body, errorPrefix = 'llm') {
|
|
25
|
+
var _a;
|
|
26
|
+
const url = `${baseUrl}/chat/completions`;
|
|
27
|
+
let response;
|
|
28
|
+
try {
|
|
29
|
+
response = yield fetch(url, {
|
|
30
|
+
method: 'POST',
|
|
31
|
+
headers: {
|
|
32
|
+
'Content-Type': 'application/json',
|
|
33
|
+
Authorization: `Bearer ${apiKey}`,
|
|
34
|
+
},
|
|
35
|
+
body: JSON.stringify(body),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
catch (cause) {
|
|
39
|
+
throw new Error(`[${errorPrefix}] ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
40
|
+
}
|
|
41
|
+
if (!response.ok) {
|
|
42
|
+
const text = yield response.text();
|
|
43
|
+
throw new Error(`[${errorPrefix}] HTTP ${response.status}: ${text}`);
|
|
44
|
+
}
|
|
45
|
+
let data;
|
|
46
|
+
try {
|
|
47
|
+
data = (yield response.json());
|
|
48
|
+
}
|
|
49
|
+
catch (cause) {
|
|
50
|
+
throw new Error(`[${errorPrefix}] Failed to parse response: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
51
|
+
}
|
|
52
|
+
const choice = (_a = data.choices) === null || _a === void 0 ? void 0 : _a[0];
|
|
53
|
+
if (!choice) {
|
|
54
|
+
throw new Error(`[${errorPrefix}] No choice in response`);
|
|
55
|
+
}
|
|
56
|
+
return data;
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
var models_1 = require("./models");
|
|
60
|
+
Object.defineProperty(exports, "MODEL_REGISTRY", { enumerable: true, get: function () { return models_1.MODEL_REGISTRY; } });
|
|
61
|
+
var bailian_1 = require("./bailian");
|
|
62
|
+
Object.defineProperty(exports, "BailianProvider", { enumerable: true, get: function () { return bailian_1.BailianProvider; } });
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { LLMRequest, LLMResponse, ProviderConfig, StreamChunk } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* LLM Provider 抽象接口。每个 Provider 实现负责对接具体的模型服务
|
|
4
|
+
*(如百炼、OpenAI、Anthropic 等),处理 HTTP 请求、流式解析和错误转换。
|
|
5
|
+
*/
|
|
6
|
+
export interface LLMProvider {
|
|
7
|
+
/** Provider 标识名,用于路由和故障转移日志 */
|
|
8
|
+
readonly name: string;
|
|
9
|
+
/** Provider 配置(API Key、Base URL、默认模型等) */
|
|
10
|
+
readonly config: ProviderConfig;
|
|
11
|
+
/**
|
|
12
|
+
* 校验当前 Provider 是否支持指定模型。
|
|
13
|
+
* 框架层在 MODEL_REGISTRY 候选过滤后,再调用此方法做二次确认。
|
|
14
|
+
* @param model - 模型标识名
|
|
15
|
+
* @returns true 表示支持,false 表示不支持(将自动轮询下一个候选)
|
|
16
|
+
*/
|
|
17
|
+
supports(model: string): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* 发送非流式请求,返回完整的模型响应。
|
|
20
|
+
* @param request - LLM 请求参数
|
|
21
|
+
* @returns 模型生成的完整响应
|
|
22
|
+
* @throws 网络异常、HTTP 错误、解析失败等均抛 {@link Error}
|
|
23
|
+
*/
|
|
24
|
+
generate(request: LLMRequest): Promise<LLMResponse>;
|
|
25
|
+
/**
|
|
26
|
+
* 发送流式请求,逐块返回模型输出。
|
|
27
|
+
* @param request - LLM 请求参数
|
|
28
|
+
* @yields 内容片段或结束标记
|
|
29
|
+
* @throws 网络异常、HTTP 错误等均抛 {@link Error}
|
|
30
|
+
*/
|
|
31
|
+
stream(request: LLMRequest): AsyncGenerator<StreamChunk, void, unknown>;
|
|
32
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 支持的模型枚举。项目层通过此枚举选择模型,Axiom 内部路由到对应 Provider。
|
|
3
|
+
*/
|
|
4
|
+
export type Model = 'qwen3.7-max' | 'qwen-plus' | 'qwen-turbo' | 'qwq-plus' | 'deepseek-v4-pro' | 'deepseek-v4-flash' | 'kimi-k2.6' | 'qwen-vl-plus';
|
|
5
|
+
/** 模型到 Provider 的映射配置 */
|
|
6
|
+
export interface ModelConfig {
|
|
7
|
+
readonly model: string;
|
|
8
|
+
readonly provider: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* 模型注册表。每个模型对应一个或多个 Provider 候选,按优先级排序。
|
|
12
|
+
* 当首选 Provider 失败时,Predictor 按此表顺序尝试下一个。
|
|
13
|
+
*/
|
|
14
|
+
export declare const MODEL_REGISTRY: Readonly<Record<Model, ReadonlyArray<ModelConfig>>>;
|