@router-agent/infra 0.0.0-stage → 0.3.32
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/dist/chat.d.ts +74 -0
- package/dist/chat.js +236 -0
- package/dist/chat.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +16 -0
- package/dist/logger.js +11 -0
- package/dist/logger.js.map +1 -0
- package/dist/plugin-install.d.ts +45 -0
- package/dist/plugin-install.js +240 -0
- package/dist/plugin-install.js.map +1 -0
- package/dist/plugin-loader.d.ts +75 -0
- package/dist/plugin-loader.js +181 -0
- package/dist/plugin-loader.js.map +1 -0
- package/dist/process.d.ts +20 -0
- package/dist/process.js +46 -0
- package/dist/process.js.map +1 -0
- package/dist/vision.d.ts +45 -0
- package/dist/vision.js +164 -0
- package/dist/vision.js.map +1 -0
- package/package.json +31 -4
- package/README.md +0 -3
package/dist/chat.d.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 通用对话补全客户端。
|
|
3
|
+
*
|
|
4
|
+
* 只依赖两种常见协议的 HTTP 接口,不引入新 SDK:
|
|
5
|
+
* - `openai-completions`:POST `{baseUrl}/chat/completions`,密钥走 `Authorization: Bearer`;
|
|
6
|
+
* - `anthropic-messages`:POST `{baseUrl}/v1/messages`,密钥走 `x-api-key`
|
|
7
|
+
* (配置了 `authHeader` 时按 `ANTHROPIC_AUTH_TOKEN` 的语义改成 `Authorization: Bearer`)。
|
|
8
|
+
*
|
|
9
|
+
* 支持工具调用(tool use):模型可以要求执行只读工具(读配置、读本地代码),
|
|
10
|
+
* 再基于工具结果给结论——这正是「排查助手要能看本机代码与配置」需要的形态。
|
|
11
|
+
*/
|
|
12
|
+
export type ChatApi = 'openai-completions' | 'anthropic-messages';
|
|
13
|
+
export interface ChatModelConfig {
|
|
14
|
+
baseUrl: string;
|
|
15
|
+
apiKey: string;
|
|
16
|
+
model: string;
|
|
17
|
+
api?: ChatApi;
|
|
18
|
+
/** anthropic-messages 下把密钥作为 Authorization: Bearer 发送。 */
|
|
19
|
+
authHeader?: boolean;
|
|
20
|
+
temperature?: number;
|
|
21
|
+
}
|
|
22
|
+
/** 工具声明(JSON Schema 形式的参数说明)。 */
|
|
23
|
+
export interface ChatToolSpec {
|
|
24
|
+
name: string;
|
|
25
|
+
description: string;
|
|
26
|
+
parameters: Record<string, unknown>;
|
|
27
|
+
}
|
|
28
|
+
/** 模型发起的一次工具调用。 */
|
|
29
|
+
export interface ChatToolCall {
|
|
30
|
+
id: string;
|
|
31
|
+
name: string;
|
|
32
|
+
/** 已解析的参数对象。 */
|
|
33
|
+
arguments: Record<string, unknown>;
|
|
34
|
+
}
|
|
35
|
+
export interface ChatMessage {
|
|
36
|
+
role: 'system' | 'user' | 'assistant' | 'tool';
|
|
37
|
+
content: string;
|
|
38
|
+
/** assistant 发起工具调用时带上。 */
|
|
39
|
+
toolCalls?: ChatToolCall[];
|
|
40
|
+
/** tool 消息指回哪一次调用。 */
|
|
41
|
+
toolCallId?: string;
|
|
42
|
+
}
|
|
43
|
+
/** 一轮对话的结果。 */
|
|
44
|
+
export interface ChatTurn {
|
|
45
|
+
/** 模型的文字输出(发起工具调用时可以为空)。 */
|
|
46
|
+
content: string;
|
|
47
|
+
/** 模型请求执行的工具。 */
|
|
48
|
+
toolCalls: ChatToolCall[];
|
|
49
|
+
}
|
|
50
|
+
export interface ChatClientOptions {
|
|
51
|
+
/** 单次请求硬超时,默认 60s。 */
|
|
52
|
+
timeoutMs?: number;
|
|
53
|
+
/** 输出 token 上限,默认 2000。 */
|
|
54
|
+
maxTokens?: number;
|
|
55
|
+
/** 测试注入点。 */
|
|
56
|
+
fetchImpl?: typeof fetch;
|
|
57
|
+
}
|
|
58
|
+
export interface ChatClient {
|
|
59
|
+
complete(messages: ChatMessage[], opts?: {
|
|
60
|
+
tools?: ChatToolSpec[];
|
|
61
|
+
}): Promise<ChatTurn>;
|
|
62
|
+
}
|
|
63
|
+
/** 创建对话补全客户端;模型地址、密钥、模型名缺一不可。 */
|
|
64
|
+
export declare function createChatClient(model: ChatModelConfig, opts?: ChatClientOptions): ChatClient;
|
|
65
|
+
/** OpenAI 兼容地址:baseUrl 填到 /v1 即可,这里补上 /chat/completions。 */
|
|
66
|
+
export declare function chatCompletionsUrl(baseUrl: string): string;
|
|
67
|
+
/** Anthropic 兼容地址:baseUrl 填网关根地址(不带 /v1/messages)。 */
|
|
68
|
+
export declare function anthropicMessagesUrl(baseUrl: string): string;
|
|
69
|
+
/** 解析一轮响应:文字 + 工具调用。 */
|
|
70
|
+
export declare function parseChatTurn(payload: unknown, api?: ChatApi): ChatTurn;
|
|
71
|
+
/** 从返回里取文本;兼容 OpenAI 的字符串 / 分段数组与 Anthropic 的 content 数组。 */
|
|
72
|
+
export declare function parseChatText(payload: unknown, api?: ChatApi): string;
|
|
73
|
+
/** 工具参数可能是 JSON 字符串,也可能是已经解析好的对象。 */
|
|
74
|
+
export declare function parseToolArguments(raw: unknown): Record<string, unknown>;
|
package/dist/chat.js
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 通用对话补全客户端。
|
|
3
|
+
*
|
|
4
|
+
* 只依赖两种常见协议的 HTTP 接口,不引入新 SDK:
|
|
5
|
+
* - `openai-completions`:POST `{baseUrl}/chat/completions`,密钥走 `Authorization: Bearer`;
|
|
6
|
+
* - `anthropic-messages`:POST `{baseUrl}/v1/messages`,密钥走 `x-api-key`
|
|
7
|
+
* (配置了 `authHeader` 时按 `ANTHROPIC_AUTH_TOKEN` 的语义改成 `Authorization: Bearer`)。
|
|
8
|
+
*
|
|
9
|
+
* 支持工具调用(tool use):模型可以要求执行只读工具(读配置、读本地代码),
|
|
10
|
+
* 再基于工具结果给结论——这正是「排查助手要能看本机代码与配置」需要的形态。
|
|
11
|
+
*/
|
|
12
|
+
const DEFAULT_TIMEOUT_MS = 60_000;
|
|
13
|
+
const DEFAULT_MAX_TOKENS = 2_000;
|
|
14
|
+
/** 创建对话补全客户端;模型地址、密钥、模型名缺一不可。 */
|
|
15
|
+
export function createChatClient(model, opts = {}) {
|
|
16
|
+
const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
|
|
17
|
+
const timeoutMs = opts.timeoutMs && opts.timeoutMs > 0 ? opts.timeoutMs : DEFAULT_TIMEOUT_MS;
|
|
18
|
+
const maxTokens = opts.maxTokens && opts.maxTokens > 0 ? opts.maxTokens : DEFAULT_MAX_TOKENS;
|
|
19
|
+
const api = model.api === 'anthropic-messages' ? 'anthropic-messages' : 'openai-completions';
|
|
20
|
+
const url = api === 'anthropic-messages' ? anthropicMessagesUrl(model.baseUrl) : chatCompletionsUrl(model.baseUrl);
|
|
21
|
+
return {
|
|
22
|
+
async complete(messages, completeOpts = {}) {
|
|
23
|
+
const controller = new AbortController();
|
|
24
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
25
|
+
let response;
|
|
26
|
+
try {
|
|
27
|
+
response = await fetchImpl(url, {
|
|
28
|
+
method: 'POST',
|
|
29
|
+
headers: {
|
|
30
|
+
'Content-Type': 'application/json',
|
|
31
|
+
...authHeaders(model, api),
|
|
32
|
+
},
|
|
33
|
+
body: JSON.stringify(requestBody(model, api, messages, maxTokens, completeOpts.tools)),
|
|
34
|
+
signal: controller.signal,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
if (isAbortError(error))
|
|
39
|
+
throw new Error(`chat:timeout(${timeoutMs}ms)`);
|
|
40
|
+
throw new Error(`chat:request-failed: ${errorText(error)}`);
|
|
41
|
+
}
|
|
42
|
+
finally {
|
|
43
|
+
clearTimeout(timer);
|
|
44
|
+
}
|
|
45
|
+
if (!response.ok) {
|
|
46
|
+
const detail = (await response.text().catch(() => '')).slice(0, 200);
|
|
47
|
+
throw new Error(`chat:http-${response.status}${detail ? `: ${detail}` : ''}`);
|
|
48
|
+
}
|
|
49
|
+
let payload;
|
|
50
|
+
try {
|
|
51
|
+
payload = await response.json();
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
throw new Error(`chat:invalid-json: ${errorText(error)}`);
|
|
55
|
+
}
|
|
56
|
+
const turn = parseChatTurn(payload, api);
|
|
57
|
+
// 既没有文字也没有工具调用,说明模型没给出可用的东西,直接报错让上层降级。
|
|
58
|
+
if (!turn.content && turn.toolCalls.length === 0)
|
|
59
|
+
throw new Error('chat:empty-response');
|
|
60
|
+
return turn;
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/** OpenAI 兼容地址:baseUrl 填到 /v1 即可,这里补上 /chat/completions。 */
|
|
65
|
+
export function chatCompletionsUrl(baseUrl) {
|
|
66
|
+
const clean = baseUrl.trim().replace(/\/+$/, '');
|
|
67
|
+
if (!clean)
|
|
68
|
+
throw new Error('chat:base-url-missing');
|
|
69
|
+
if (clean.endsWith('/chat/completions'))
|
|
70
|
+
return clean;
|
|
71
|
+
return `${clean}/chat/completions`;
|
|
72
|
+
}
|
|
73
|
+
/** Anthropic 兼容地址:baseUrl 填网关根地址(不带 /v1/messages)。 */
|
|
74
|
+
export function anthropicMessagesUrl(baseUrl) {
|
|
75
|
+
const clean = baseUrl.trim().replace(/\/+$/, '');
|
|
76
|
+
if (!clean)
|
|
77
|
+
throw new Error('chat:base-url-missing');
|
|
78
|
+
if (clean.endsWith('/v1/messages'))
|
|
79
|
+
return clean;
|
|
80
|
+
if (clean.endsWith('/messages'))
|
|
81
|
+
return clean;
|
|
82
|
+
return `${clean}/v1/messages`;
|
|
83
|
+
}
|
|
84
|
+
function authHeaders(model, api) {
|
|
85
|
+
if (!model.apiKey)
|
|
86
|
+
return {};
|
|
87
|
+
if (api === 'anthropic-messages') {
|
|
88
|
+
return model.authHeader
|
|
89
|
+
? { Authorization: `Bearer ${model.apiKey}` }
|
|
90
|
+
: { 'x-api-key': model.apiKey, 'anthropic-version': '2023-06-01' };
|
|
91
|
+
}
|
|
92
|
+
return { Authorization: `Bearer ${model.apiKey}` };
|
|
93
|
+
}
|
|
94
|
+
function requestBody(model, api, messages, maxTokens, tools) {
|
|
95
|
+
const temperature = model.temperature ?? 0.2;
|
|
96
|
+
if (api === 'anthropic-messages') {
|
|
97
|
+
const system = messages.filter(item => item.role === 'system').map(item => item.content).join('\n\n');
|
|
98
|
+
const rest = messages.filter(item => item.role !== 'system');
|
|
99
|
+
return {
|
|
100
|
+
model: model.model,
|
|
101
|
+
max_tokens: maxTokens,
|
|
102
|
+
temperature,
|
|
103
|
+
...(system ? { system } : {}),
|
|
104
|
+
...(tools && tools.length > 0 ? { tools: tools.map(anthropicTool) } : {}),
|
|
105
|
+
messages: rest.map(anthropicMessage),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
model: model.model,
|
|
110
|
+
max_tokens: maxTokens,
|
|
111
|
+
temperature,
|
|
112
|
+
...(tools && tools.length > 0 ? { tools: tools.map(openaiTool) } : {}),
|
|
113
|
+
messages: messages.map(openaiMessage),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function openaiTool(tool) {
|
|
117
|
+
return {
|
|
118
|
+
type: 'function',
|
|
119
|
+
function: { name: tool.name, description: tool.description, parameters: tool.parameters },
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function anthropicTool(tool) {
|
|
123
|
+
return { name: tool.name, description: tool.description, input_schema: tool.parameters };
|
|
124
|
+
}
|
|
125
|
+
function openaiMessage(message) {
|
|
126
|
+
if (message.role === 'tool') {
|
|
127
|
+
return { role: 'tool', tool_call_id: message.toolCallId ?? '', content: message.content };
|
|
128
|
+
}
|
|
129
|
+
if (message.role === 'assistant' && message.toolCalls && message.toolCalls.length > 0) {
|
|
130
|
+
return {
|
|
131
|
+
role: 'assistant',
|
|
132
|
+
content: message.content || null,
|
|
133
|
+
tool_calls: message.toolCalls.map(call => ({
|
|
134
|
+
id: call.id,
|
|
135
|
+
type: 'function',
|
|
136
|
+
function: { name: call.name, arguments: JSON.stringify(call.arguments ?? {}) },
|
|
137
|
+
})),
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
return { role: message.role, content: message.content };
|
|
141
|
+
}
|
|
142
|
+
function anthropicMessage(message) {
|
|
143
|
+
if (message.role === 'tool') {
|
|
144
|
+
return {
|
|
145
|
+
role: 'user',
|
|
146
|
+
content: [{ type: 'tool_result', tool_use_id: message.toolCallId ?? '', content: message.content }],
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
if (message.role === 'assistant' && message.toolCalls && message.toolCalls.length > 0) {
|
|
150
|
+
const blocks = [];
|
|
151
|
+
if (message.content)
|
|
152
|
+
blocks.push({ type: 'text', text: message.content });
|
|
153
|
+
for (const call of message.toolCalls) {
|
|
154
|
+
blocks.push({ type: 'tool_use', id: call.id, name: call.name, input: call.arguments ?? {} });
|
|
155
|
+
}
|
|
156
|
+
return { role: 'assistant', content: blocks };
|
|
157
|
+
}
|
|
158
|
+
return { role: message.role, content: message.content };
|
|
159
|
+
}
|
|
160
|
+
/** 解析一轮响应:文字 + 工具调用。 */
|
|
161
|
+
export function parseChatTurn(payload, api = 'openai-completions') {
|
|
162
|
+
const root = payload;
|
|
163
|
+
if (!root)
|
|
164
|
+
return { content: '', toolCalls: [] };
|
|
165
|
+
if (api === 'anthropic-messages') {
|
|
166
|
+
const blocks = Array.isArray(root.content) ? root.content : [];
|
|
167
|
+
const content = blocks
|
|
168
|
+
.filter((block) => block?.type === 'text')
|
|
169
|
+
.map((block) => String(block.text ?? ''))
|
|
170
|
+
.join('')
|
|
171
|
+
.trim();
|
|
172
|
+
const toolCalls = blocks
|
|
173
|
+
.filter((block) => block?.type === 'tool_use')
|
|
174
|
+
.map((block) => ({
|
|
175
|
+
id: String(block.id ?? ''),
|
|
176
|
+
name: String(block.name ?? ''),
|
|
177
|
+
arguments: block.input ?? {},
|
|
178
|
+
}));
|
|
179
|
+
return { content, toolCalls };
|
|
180
|
+
}
|
|
181
|
+
const message = root.choices?.[0]?.message;
|
|
182
|
+
const content = parseChatContent(message?.content);
|
|
183
|
+
const rawCalls = Array.isArray(message?.tool_calls) ? message.tool_calls : [];
|
|
184
|
+
const toolCalls = rawCalls.map((call) => ({
|
|
185
|
+
id: String(call?.id ?? ''),
|
|
186
|
+
name: String(call?.function?.name ?? ''),
|
|
187
|
+
arguments: parseToolArguments(call?.function?.arguments),
|
|
188
|
+
}));
|
|
189
|
+
return { content, toolCalls };
|
|
190
|
+
}
|
|
191
|
+
/** 从返回里取文本;兼容 OpenAI 的字符串 / 分段数组与 Anthropic 的 content 数组。 */
|
|
192
|
+
export function parseChatText(payload, api = 'openai-completions') {
|
|
193
|
+
const root = payload;
|
|
194
|
+
if (!root)
|
|
195
|
+
return '';
|
|
196
|
+
if (api === 'anthropic-messages') {
|
|
197
|
+
const blocks = Array.isArray(root.content) ? root.content : [];
|
|
198
|
+
return blocks
|
|
199
|
+
.map((block) => (block && typeof block.text === 'string' ? block.text : ''))
|
|
200
|
+
.join('')
|
|
201
|
+
.trim();
|
|
202
|
+
}
|
|
203
|
+
return parseChatContent(root.choices?.[0]?.message?.content);
|
|
204
|
+
}
|
|
205
|
+
function parseChatContent(content) {
|
|
206
|
+
if (typeof content === 'string')
|
|
207
|
+
return content.trim();
|
|
208
|
+
if (Array.isArray(content)) {
|
|
209
|
+
return content
|
|
210
|
+
.map((part) => (part && part.type === 'text' ? String(part.text ?? '') : ''))
|
|
211
|
+
.join('')
|
|
212
|
+
.trim();
|
|
213
|
+
}
|
|
214
|
+
return '';
|
|
215
|
+
}
|
|
216
|
+
/** 工具参数可能是 JSON 字符串,也可能是已经解析好的对象。 */
|
|
217
|
+
export function parseToolArguments(raw) {
|
|
218
|
+
if (raw && typeof raw === 'object')
|
|
219
|
+
return raw;
|
|
220
|
+
if (typeof raw !== 'string' || !raw.trim())
|
|
221
|
+
return {};
|
|
222
|
+
try {
|
|
223
|
+
const parsed = JSON.parse(raw);
|
|
224
|
+
return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : {};
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
return {};
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
function isAbortError(error) {
|
|
231
|
+
return error instanceof Error && (error.name === 'AbortError' || /aborted/i.test(error.message));
|
|
232
|
+
}
|
|
233
|
+
function errorText(error) {
|
|
234
|
+
return error instanceof Error ? error.message : String(error);
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=chat.js.map
|
package/dist/chat.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat.js","sourceRoot":"","sources":["../../../../packages/infra/src/chat.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 基础设施包入口。
|
|
3
|
+
*
|
|
4
|
+
* `chat.ts` 与 `vision.ts` 各自保留了同名的 OpenAI 地址规范化函数(错误码不同),
|
|
5
|
+
* 这里显式只导出 chat 版本,避免 barrel 出现二义性;vision 版本仍可从模块深路径引用。
|
|
6
|
+
*/
|
|
7
|
+
export * from './logger.js';
|
|
8
|
+
export * from './process.js';
|
|
9
|
+
export * from './chat.js';
|
|
10
|
+
export * from './plugin-loader.js';
|
|
11
|
+
export * from './plugin-install.js';
|
|
12
|
+
export { createVisionTranscriber, type ImageInput, type ImageTranscriber, type VisionModelConfig, } from './vision.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 基础设施包入口。
|
|
3
|
+
*
|
|
4
|
+
* `chat.ts` 与 `vision.ts` 各自保留了同名的 OpenAI 地址规范化函数(错误码不同),
|
|
5
|
+
* 这里显式只导出 chat 版本,避免 barrel 出现二义性;vision 版本仍可从模块深路径引用。
|
|
6
|
+
*/
|
|
7
|
+
export * from './logger.js';
|
|
8
|
+
export * from './process.js';
|
|
9
|
+
export * from './chat.js';
|
|
10
|
+
export * from './plugin-loader.js';
|
|
11
|
+
export * from './plugin-install.js';
|
|
12
|
+
export { createVisionTranscriber, } from './vision.js';
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/infra/src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA;AACzB,cAAc,oBAAoB,CAAA;AAClC,cAAc,qBAAqB,CAAA;AACnC,OAAO,EACL,uBAAuB,GAIxB,MAAM,aAAa,CAAA"}
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 结构化日志的统一入口。
|
|
3
|
+
*
|
|
4
|
+
* 服务日志一行一个 JSON(`at` / `level` / `message` + 业务字段),
|
|
5
|
+
* 面板日志页按 info / warn / error 三档过滤,所以这里只保留这三档。
|
|
6
|
+
* 各模块只依赖这个接口,不直接碰文件,方便测试注入与将来换实现。
|
|
7
|
+
*/
|
|
8
|
+
export interface Logger {
|
|
9
|
+
info(message: string, extra?: Record<string, unknown>): void;
|
|
10
|
+
warn(message: string, extra?: Record<string, unknown>): void;
|
|
11
|
+
error(message: string, extra?: Record<string, unknown>): void;
|
|
12
|
+
}
|
|
13
|
+
/** 未注入日志实现时的空实现;关键链路不会因为「没传 logger」而崩。 */
|
|
14
|
+
export declare const noopLogger: Logger;
|
|
15
|
+
/** 把任意异常折成一行可读文本;日志里不写堆栈,避免刷屏。 */
|
|
16
|
+
export declare function errorMessage(error: unknown): string;
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** 未注入日志实现时的空实现;关键链路不会因为「没传 logger」而崩。 */
|
|
2
|
+
export const noopLogger = {
|
|
3
|
+
info: () => { },
|
|
4
|
+
warn: () => { },
|
|
5
|
+
error: () => { },
|
|
6
|
+
};
|
|
7
|
+
/** 把任意异常折成一行可读文本;日志里不写堆栈,避免刷屏。 */
|
|
8
|
+
export function errorMessage(error) {
|
|
9
|
+
return error instanceof Error ? error.message : String(error);
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../../packages/infra/src/logger.ts"],"names":[],"mappings":"AAaA,0CAA0C;AAC1C,MAAM,CAAC,MAAM,UAAU,GAAW;IAChC,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;IACd,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;IACd,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;CAChB,CAAA;AAED,kCAAkC;AAClC,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;AAC/D,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type Logger } from './logger.js';
|
|
2
|
+
/** npm 执行器;测试里可以注入假的实现。 */
|
|
3
|
+
export type NpmRunner = (args: string[], opts: {
|
|
4
|
+
cwd: string;
|
|
5
|
+
env: NodeJS.ProcessEnv;
|
|
6
|
+
timeoutMs: number;
|
|
7
|
+
onLine: (line: string) => void;
|
|
8
|
+
}) => Promise<number>;
|
|
9
|
+
export interface PluginInstallOptions {
|
|
10
|
+
home: string;
|
|
11
|
+
/** 纯 npm 包名,不能是本地路径。 */
|
|
12
|
+
packageName: string;
|
|
13
|
+
/** 精确版本或 'latest';缺省 latest。 */
|
|
14
|
+
version?: string;
|
|
15
|
+
env?: NodeJS.ProcessEnv;
|
|
16
|
+
timeoutMs?: number;
|
|
17
|
+
onLine?: (line: string) => void;
|
|
18
|
+
logger?: Logger;
|
|
19
|
+
/** 测试注入:执行 npm,返回退出码。 */
|
|
20
|
+
runNpm?: NpmRunner;
|
|
21
|
+
}
|
|
22
|
+
export interface PluginInstallResult {
|
|
23
|
+
ok: boolean;
|
|
24
|
+
version?: string;
|
|
25
|
+
log: string[];
|
|
26
|
+
error?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 从插件入口里取出 npm 包名。
|
|
30
|
+
*
|
|
31
|
+
* 本地路径(`./x` / `/x` / `file:`)、URL 和带空格的写法都返回 undefined;
|
|
32
|
+
* 调用方据此区分「需要安装」与「重启即可生效」。
|
|
33
|
+
*/
|
|
34
|
+
export declare function npmPackageNameOf(value: string): string | undefined;
|
|
35
|
+
/** npm 全局安装的同一套命令名:Windows 上是 npm.cmd。 */
|
|
36
|
+
export declare function npmBin(): string;
|
|
37
|
+
/** 读已安装包的版本;没装或 package.json 损坏时返回 null。 */
|
|
38
|
+
export declare function installedPluginVersion(home: string, packageName: string): string | null;
|
|
39
|
+
/**
|
|
40
|
+
* 把 npm 包安装到 `<RA_HOME>/node_modules`。
|
|
41
|
+
*
|
|
42
|
+
* 安装完成后会用插件加载器同一套解析逻辑确认包能被找到;解析不到的包
|
|
43
|
+
* 即使用 npm 装上了,服务重启时也加载不了,所以这里按失败返回。
|
|
44
|
+
*/
|
|
45
|
+
export declare function installPluginPackage(opts: PluginInstallOptions): Promise<PluginInstallResult>;
|