@easynet/agent-llm 1.0.14 → 1.0.16
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/api/create-agent-llm.d.ts +1 -19
- package/dist/api/create-agent-llm.d.ts.map +1 -1
- package/dist/{chunk-VHC4NEWF.js → chunk-CWU7GNFB.js} +117 -255
- package/dist/chunk-CWU7GNFB.js.map +1 -0
- package/dist/cli/index.d.ts +0 -7
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +3 -7
- package/dist/cli/index.js.map +1 -1
- package/dist/config/index.d.ts +0 -3
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/loader.d.ts +0 -14
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/parser.d.ts +0 -3
- package/dist/config/parser.d.ts.map +1 -1
- package/dist/connectivity/check.d.ts +12 -13
- package/dist/connectivity/check.d.ts.map +1 -1
- package/dist/connectivity/index.d.ts +2 -4
- package/dist/connectivity/index.d.ts.map +1 -1
- package/dist/connectivity/types.d.ts +0 -11
- package/dist/connectivity/types.d.ts.map +1 -1
- package/dist/extensions/index.d.ts +2 -5
- package/dist/extensions/index.d.ts.map +1 -1
- package/dist/extensions/loader.d.ts +1 -17
- package/dist/extensions/loader.d.ts.map +1 -1
- package/dist/extensions/npm-protocol.d.ts +2 -33
- package/dist/extensions/npm-protocol.d.ts.map +1 -1
- package/dist/index.d.ts +9 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -41
- package/dist/index.js.map +1 -1
- package/dist/langchain/index.d.ts +13 -3
- package/dist/langchain/index.d.ts.map +1 -1
- package/dist/registry/chat-model.d.ts +1 -8
- package/dist/registry/chat-model.d.ts.map +1 -1
- package/dist/registry/index.d.ts +0 -5
- package/dist/registry/index.d.ts.map +1 -1
- package/dist/types.d.ts +8 -165
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -5
- package/dist/chunk-VHC4NEWF.js.map +0 -1
- package/dist/langchain/adapter.d.ts +0 -21
- package/dist/langchain/adapter.d.ts.map +0 -1
- package/dist/providers/index.d.ts +0 -7
- package/dist/providers/index.d.ts.map +0 -1
- package/dist/providers/openai.d.ts +0 -9
- package/dist/providers/openai.d.ts.map +0 -1
- package/dist/registry/client.d.ts +0 -13
- package/dist/registry/client.d.ts.map +0 -1
|
@@ -1,29 +1,11 @@
|
|
|
1
|
-
import { createChatModelFromLlmConfig } from "../langchain/
|
|
1
|
+
import { createChatModelFromLlmConfig } from "../langchain/index.js";
|
|
2
2
|
import type { ConnectionStatus } from "../connectivity/types.js";
|
|
3
3
|
export interface CreateAgentLlMOptions {
|
|
4
|
-
/** Path to YAML config file. If omitted, uses llm.yaml in the current directory (cwd). */
|
|
5
4
|
configPath?: string;
|
|
6
|
-
/** If true (default), run npm install when provider is npm:<package> and package is not found. */
|
|
7
5
|
installNpmIfMissing?: boolean;
|
|
8
|
-
/**
|
|
9
|
-
* If true (default when any endpoint has baseURL), check connectivity to CIS/LLM endpoints before use.
|
|
10
|
-
* When unreachable, throws with a reminder to connect to Secure VPN.
|
|
11
|
-
*/
|
|
12
6
|
checkConnectivity?: boolean;
|
|
13
|
-
/**
|
|
14
|
-
* Callback for real-time connection status (e.g. "checking", "reachable", "unreachable").
|
|
15
|
-
* Use this to display live status in the UI.
|
|
16
|
-
*/
|
|
17
7
|
onConnectionStatus?: (status: ConnectionStatus) => void;
|
|
18
|
-
/** Timeout in ms for each connectivity check. Default 8000. */
|
|
19
8
|
connectivityTimeoutMs?: number;
|
|
20
9
|
}
|
|
21
|
-
/**
|
|
22
|
-
* Create a LangChain-formatted LLM from config. Resolves npm: providers and optionally installs packages.
|
|
23
|
-
* Checks connectivity to CIS/LLM endpoints by default and reports real-time status via onConnectionStatus.
|
|
24
|
-
* - createAgentLlM() — uses llm.yaml in the current directory
|
|
25
|
-
* - createAgentLlM("path/to/llm.yaml") — use specific config file
|
|
26
|
-
* - createAgentLlM({ configPath: "...", onConnectionStatus: (s) => console.log(s) }) — options object
|
|
27
|
-
*/
|
|
28
10
|
export declare function createAgentLlM(configPathOrOptions?: string | CreateAgentLlMOptions): Promise<ReturnType<typeof createChatModelFromLlmConfig>>;
|
|
29
11
|
//# sourceMappingURL=create-agent-llm.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-agent-llm.d.ts","sourceRoot":"","sources":["../../src/api/create-agent-llm.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"create-agent-llm.d.ts","sourceRoot":"","sources":["../../src/api/create-agent-llm.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAC;AAUrE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAsCjE,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACxD,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAgFD,wBAAsB,cAAc,CAClC,mBAAmB,CAAC,EAAE,MAAM,GAAG,qBAAqB,GACnD,OAAO,CAAC,UAAU,CAAC,OAAO,4BAA4B,CAAC,CAAC,CA0B1D"}
|
|
@@ -153,207 +153,6 @@ function loadLlmConfig(filePath, options = {}) {
|
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
-
// src/providers/openai.ts
|
|
157
|
-
import OpenAI from "openai";
|
|
158
|
-
function getApiKey(config) {
|
|
159
|
-
const key = config.apiKey ?? process.env.OPENAI_API_KEY ?? "";
|
|
160
|
-
if (!key) throw new Error("OpenAI-compatible apiKey required (config.apiKey or OPENAI_API_KEY)");
|
|
161
|
-
return key;
|
|
162
|
-
}
|
|
163
|
-
function createOpenAIClientOptions(config) {
|
|
164
|
-
const opts = { apiKey: getApiKey(config) };
|
|
165
|
-
if (typeof config.baseURL === "string" && config.baseURL) opts.baseURL = config.baseURL;
|
|
166
|
-
return opts;
|
|
167
|
-
}
|
|
168
|
-
function serializeMessage(m) {
|
|
169
|
-
if (m.role === "tool")
|
|
170
|
-
return { role: "tool", content: m.content, tool_call_id: m.tool_call_id };
|
|
171
|
-
if (m.role === "assistant" && "tool_calls" in m && m.tool_calls?.length) {
|
|
172
|
-
return {
|
|
173
|
-
role: "assistant",
|
|
174
|
-
content: m.content ?? null,
|
|
175
|
-
tool_calls: m.tool_calls.map((tc) => ({
|
|
176
|
-
id: tc.id,
|
|
177
|
-
type: "function",
|
|
178
|
-
function: { name: tc.function.name, arguments: tc.function.arguments }
|
|
179
|
-
}))
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
return { role: m.role, content: m.content };
|
|
183
|
-
}
|
|
184
|
-
function createOpenAIChatClient(config) {
|
|
185
|
-
const client = new OpenAI(createOpenAIClientOptions(config));
|
|
186
|
-
const model = config.model ?? process.env.OPENAI_MODEL ?? "gpt-4o-mini";
|
|
187
|
-
const temperature = config.temperature ?? 0;
|
|
188
|
-
return {
|
|
189
|
-
id: config.id,
|
|
190
|
-
type: "chat",
|
|
191
|
-
async chat(messages) {
|
|
192
|
-
const resp = await client.chat.completions.create({
|
|
193
|
-
model,
|
|
194
|
-
temperature,
|
|
195
|
-
messages: messages.map((m) => ({ role: m.role, content: m.content }))
|
|
196
|
-
});
|
|
197
|
-
const content = resp.choices[0]?.message?.content ?? "";
|
|
198
|
-
const usage = resp.usage ? { promptTokens: resp.usage.prompt_tokens, completionTokens: resp.usage.completion_tokens } : void 0;
|
|
199
|
-
return { content, usage };
|
|
200
|
-
},
|
|
201
|
-
async *chatStream(messages) {
|
|
202
|
-
const stream = await client.chat.completions.create({
|
|
203
|
-
model,
|
|
204
|
-
temperature,
|
|
205
|
-
messages: messages.map((m) => ({ role: m.role, content: m.content })),
|
|
206
|
-
stream: true
|
|
207
|
-
});
|
|
208
|
-
let usage;
|
|
209
|
-
for await (const chunk of stream) {
|
|
210
|
-
const delta = chunk.choices[0]?.delta;
|
|
211
|
-
const content = delta?.content ?? "";
|
|
212
|
-
const finishReason = chunk.choices[0]?.finish_reason;
|
|
213
|
-
if (chunk.usage) {
|
|
214
|
-
usage = {
|
|
215
|
-
promptTokens: chunk.usage.prompt_tokens,
|
|
216
|
-
completionTokens: chunk.usage.completion_tokens
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
yield {
|
|
220
|
-
content,
|
|
221
|
-
done: finishReason !== null && finishReason !== void 0,
|
|
222
|
-
usage
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
},
|
|
226
|
-
async chatWithTools(messages, tools, _options) {
|
|
227
|
-
const resp = await client.chat.completions.create({
|
|
228
|
-
model,
|
|
229
|
-
temperature,
|
|
230
|
-
messages: messages.map(serializeMessage),
|
|
231
|
-
tools: tools.map((t) => ({
|
|
232
|
-
type: "function",
|
|
233
|
-
function: {
|
|
234
|
-
name: t.function.name,
|
|
235
|
-
description: t.function.description,
|
|
236
|
-
parameters: t.function.parameters ?? void 0
|
|
237
|
-
}
|
|
238
|
-
}))
|
|
239
|
-
});
|
|
240
|
-
const msg = resp.choices[0]?.message;
|
|
241
|
-
const usage = resp.usage ? { promptTokens: resp.usage.prompt_tokens, completionTokens: resp.usage.completion_tokens } : void 0;
|
|
242
|
-
return {
|
|
243
|
-
message: {
|
|
244
|
-
role: "assistant",
|
|
245
|
-
content: msg?.content ?? null,
|
|
246
|
-
tool_calls: msg?.tool_calls?.map((tc) => ({
|
|
247
|
-
id: tc.id,
|
|
248
|
-
type: "function",
|
|
249
|
-
function: {
|
|
250
|
-
name: tc.function?.name ?? "",
|
|
251
|
-
arguments: tc.function?.arguments ?? ""
|
|
252
|
-
}
|
|
253
|
-
}))
|
|
254
|
-
},
|
|
255
|
-
usage
|
|
256
|
-
};
|
|
257
|
-
},
|
|
258
|
-
async *chatWithToolsStream(messages, tools, _options) {
|
|
259
|
-
const stream = await client.chat.completions.create({
|
|
260
|
-
model,
|
|
261
|
-
temperature,
|
|
262
|
-
messages: messages.map(serializeMessage),
|
|
263
|
-
tools: tools.map((t) => ({
|
|
264
|
-
type: "function",
|
|
265
|
-
function: {
|
|
266
|
-
name: t.function.name,
|
|
267
|
-
description: t.function.description,
|
|
268
|
-
parameters: t.function.parameters ?? void 0
|
|
269
|
-
}
|
|
270
|
-
})),
|
|
271
|
-
stream: true,
|
|
272
|
-
stream_options: { include_usage: true }
|
|
273
|
-
});
|
|
274
|
-
let usage;
|
|
275
|
-
for await (const chunk of stream) {
|
|
276
|
-
const delta = chunk.choices[0]?.delta;
|
|
277
|
-
const finishReason = chunk.choices[0]?.finish_reason;
|
|
278
|
-
if (chunk.usage) {
|
|
279
|
-
usage = {
|
|
280
|
-
promptTokens: chunk.usage.prompt_tokens,
|
|
281
|
-
completionTokens: chunk.usage.completion_tokens
|
|
282
|
-
};
|
|
283
|
-
}
|
|
284
|
-
const toolCalls = delta?.tool_calls?.map((tc) => ({
|
|
285
|
-
index: tc.index,
|
|
286
|
-
id: tc.id,
|
|
287
|
-
type: tc.type,
|
|
288
|
-
function: tc.function ? {
|
|
289
|
-
name: tc.function.name,
|
|
290
|
-
arguments: tc.function.arguments
|
|
291
|
-
} : void 0
|
|
292
|
-
}));
|
|
293
|
-
yield {
|
|
294
|
-
delta: {
|
|
295
|
-
role: delta?.role,
|
|
296
|
-
content: delta?.content ?? null,
|
|
297
|
-
tool_calls: toolCalls
|
|
298
|
-
},
|
|
299
|
-
done: finishReason !== null && finishReason !== void 0,
|
|
300
|
-
usage
|
|
301
|
-
};
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
};
|
|
305
|
-
}
|
|
306
|
-
function createOpenAIImageClient(config) {
|
|
307
|
-
const client = new OpenAI(createOpenAIClientOptions(config));
|
|
308
|
-
const model = config.model ?? "dall-e-3";
|
|
309
|
-
return {
|
|
310
|
-
id: config.id,
|
|
311
|
-
type: "image",
|
|
312
|
-
async chat() {
|
|
313
|
-
throw new Error("OpenAI image model does not support chat; use generateImage()");
|
|
314
|
-
},
|
|
315
|
-
async generateImage(options) {
|
|
316
|
-
const resp = await client.images.generate({
|
|
317
|
-
model,
|
|
318
|
-
prompt: options.prompt,
|
|
319
|
-
size: options.size ?? "1024x1024",
|
|
320
|
-
n: options.n ?? 1,
|
|
321
|
-
response_format: "url"
|
|
322
|
-
});
|
|
323
|
-
const url = resp.data?.[0]?.url ?? void 0;
|
|
324
|
-
return { url };
|
|
325
|
-
}
|
|
326
|
-
};
|
|
327
|
-
}
|
|
328
|
-
function createOpenAIClient(config) {
|
|
329
|
-
if (config.type === "image") return createOpenAIImageClient(config);
|
|
330
|
-
return createOpenAIChatClient(config);
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
// src/providers/index.ts
|
|
334
|
-
var OPENAI_COMPATIBLE = "openai-compatible";
|
|
335
|
-
function createOpenAICompat(config) {
|
|
336
|
-
return createOpenAIClient(config);
|
|
337
|
-
}
|
|
338
|
-
var PROVIDERS = {
|
|
339
|
-
openai: createOpenAICompat,
|
|
340
|
-
[OPENAI_COMPATIBLE]: createOpenAICompat
|
|
341
|
-
};
|
|
342
|
-
function createClient(config) {
|
|
343
|
-
const p = (config.provider ?? "").toLowerCase();
|
|
344
|
-
const fn = PROVIDERS[p];
|
|
345
|
-
if (!fn) {
|
|
346
|
-
const supported = [.../* @__PURE__ */ new Set([...Object.keys(PROVIDERS), "extension providers"])].sort().join(", ");
|
|
347
|
-
throw new Error(
|
|
348
|
-
`Unsupported LLM provider: ${config.provider}. Supported: ${supported}.`
|
|
349
|
-
);
|
|
350
|
-
}
|
|
351
|
-
return fn(config);
|
|
352
|
-
}
|
|
353
|
-
function registerProvider(name, factory) {
|
|
354
|
-
PROVIDERS[name.toLowerCase()] = factory;
|
|
355
|
-
}
|
|
356
|
-
|
|
357
156
|
// src/registry/chat-model.ts
|
|
358
157
|
var CHAT_MODEL_FACTORIES = /* @__PURE__ */ new Map();
|
|
359
158
|
function registerChatModelProvider(providerName, factory) {
|
|
@@ -363,10 +162,10 @@ function getChatModelFactory(providerName) {
|
|
|
363
162
|
return CHAT_MODEL_FACTORIES.get(providerName.toLowerCase());
|
|
364
163
|
}
|
|
365
164
|
|
|
366
|
-
// src/langchain/
|
|
165
|
+
// src/langchain/index.ts
|
|
367
166
|
import { ChatOpenAI } from "@langchain/openai";
|
|
368
167
|
var DEFAULT_MODEL = "gpt-4o-mini";
|
|
369
|
-
function
|
|
168
|
+
function normalizeError(e, context) {
|
|
370
169
|
if (e instanceof Error) return new Error(`${context}: ${e.message}`, { cause: e });
|
|
371
170
|
return new Error(`${context}: ${String(e)}`);
|
|
372
171
|
}
|
|
@@ -379,7 +178,7 @@ function createChatModelFromLlmConfig(options) {
|
|
|
379
178
|
defaultId = parsed.defaultId;
|
|
380
179
|
configs = parsed.configs;
|
|
381
180
|
} catch (e) {
|
|
382
|
-
throw
|
|
181
|
+
throw normalizeError(e, "agent-llm: failed to parse llm section");
|
|
383
182
|
}
|
|
384
183
|
const defaultConfig = configs.find((c) => c.id === defaultId) ?? configs[0];
|
|
385
184
|
if (!defaultConfig) {
|
|
@@ -392,7 +191,7 @@ function createChatModelFromLlmConfig(options) {
|
|
|
392
191
|
...apiKey2 ? { apiKey: apiKey2 } : {}
|
|
393
192
|
});
|
|
394
193
|
} catch (e) {
|
|
395
|
-
throw
|
|
194
|
+
throw normalizeError(e, "agent-llm: failed to create default ChatOpenAI");
|
|
396
195
|
}
|
|
397
196
|
}
|
|
398
197
|
const provider = defaultConfig.provider ?? "openai";
|
|
@@ -406,7 +205,7 @@ function createChatModelFromLlmConfig(options) {
|
|
|
406
205
|
try {
|
|
407
206
|
return chatModelFactory(config);
|
|
408
207
|
} catch (e) {
|
|
409
|
-
throw
|
|
208
|
+
throw normalizeError(e, `agent-llm: failed to create ChatModel for provider "${provider}"`);
|
|
410
209
|
}
|
|
411
210
|
}
|
|
412
211
|
const model = modelEnv ?? defaultConfig?.model ?? process.env.OPENAI_MODEL ?? DEFAULT_MODEL;
|
|
@@ -428,10 +227,13 @@ function createChatModelFromLlmConfig(options) {
|
|
|
428
227
|
try {
|
|
429
228
|
return new ChatOpenAI(constructorOptions);
|
|
430
229
|
} catch (e) {
|
|
431
|
-
throw
|
|
230
|
+
throw normalizeError(e, "agent-llm: failed to create ChatOpenAI from config");
|
|
432
231
|
}
|
|
433
232
|
}
|
|
434
233
|
|
|
234
|
+
// src/types.ts
|
|
235
|
+
var AGENT_LLM_PROVIDER_FIELD = "agentLlmProvider";
|
|
236
|
+
|
|
435
237
|
// src/extensions/loader.ts
|
|
436
238
|
import { readdirSync, readFileSync as readFileSync2, existsSync as existsSync2 } from "fs";
|
|
437
239
|
import { join } from "path";
|
|
@@ -442,12 +244,11 @@ function isLLMExtension(m) {
|
|
|
442
244
|
const e = m;
|
|
443
245
|
if (typeof e.providerName !== "string") return false;
|
|
444
246
|
const hasRegister = typeof e.register === "function";
|
|
445
|
-
const
|
|
446
|
-
return hasRegister ||
|
|
247
|
+
const hasChatModel = typeof e.createChatModel === "function";
|
|
248
|
+
return hasRegister || hasChatModel;
|
|
447
249
|
}
|
|
448
250
|
function registerExtension(ext) {
|
|
449
|
-
if (typeof ext.
|
|
450
|
-
registerProvider(ext.providerName, ext.createClient);
|
|
251
|
+
if (typeof ext.createChatModel === "function") {
|
|
451
252
|
registerChatModelProvider(ext.providerName, ext.createChatModel);
|
|
452
253
|
return;
|
|
453
254
|
}
|
|
@@ -476,7 +277,7 @@ function readPackageProviderName(pkgPath) {
|
|
|
476
277
|
try {
|
|
477
278
|
const raw = readFileSync2(pkgPath, "utf-8");
|
|
478
279
|
const pkg = JSON.parse(raw);
|
|
479
|
-
const declared = pkg
|
|
280
|
+
const declared = pkg[AGENT_LLM_PROVIDER_FIELD] === true || Array.isArray(pkg.keywords) && pkg.keywords.includes("agent-llm-provider");
|
|
480
281
|
return declared && typeof pkg.name === "string" ? pkg.name : null;
|
|
481
282
|
} catch {
|
|
482
283
|
return null;
|
|
@@ -672,11 +473,7 @@ async function ensureNpmPackageInstalled(packageName, options = {}) {
|
|
|
672
473
|
if (installed !== null && installed !== resolvedVersion) {
|
|
673
474
|
const installSpec2 = `${packageName}@${resolvedVersion}`;
|
|
674
475
|
try {
|
|
675
|
-
execFileSync("npm", ["install", installSpec2], {
|
|
676
|
-
cwd,
|
|
677
|
-
stdio: "inherit",
|
|
678
|
-
encoding: "utf-8"
|
|
679
|
-
});
|
|
476
|
+
execFileSync("npm", ["install", installSpec2], { cwd, stdio: "inherit", encoding: "utf-8" });
|
|
680
477
|
} catch (e) {
|
|
681
478
|
const msg = e instanceof Error ? e.message : String(e);
|
|
682
479
|
throw new Error(`agent-llm: npm install failed for ${installSpec2}: ${msg}`, { cause: e });
|
|
@@ -689,20 +486,14 @@ async function ensureNpmPackageInstalled(packageName, options = {}) {
|
|
|
689
486
|
}
|
|
690
487
|
const installSpec = resolvedVersion ? `${packageName}@${resolvedVersion}` : packageName;
|
|
691
488
|
try {
|
|
692
|
-
execFileSync("npm", ["install", installSpec], {
|
|
693
|
-
cwd,
|
|
694
|
-
stdio: "inherit",
|
|
695
|
-
encoding: "utf-8"
|
|
696
|
-
});
|
|
489
|
+
execFileSync("npm", ["install", installSpec], { cwd, stdio: "inherit", encoding: "utf-8" });
|
|
697
490
|
} catch (e) {
|
|
698
491
|
const msg = e instanceof Error ? e.message : String(e);
|
|
699
492
|
throw new Error(`agent-llm: npm install failed for ${installSpec}: ${msg}`, { cause: e });
|
|
700
493
|
}
|
|
701
494
|
}
|
|
702
|
-
function
|
|
703
|
-
if (e instanceof Error) {
|
|
704
|
-
return new Error(`${context}: ${e.message}`, { cause: e });
|
|
705
|
-
}
|
|
495
|
+
function normalizeError2(e, context) {
|
|
496
|
+
if (e instanceof Error) return new Error(`${context}: ${e.message}`, { cause: e });
|
|
706
497
|
return new Error(`${context}: ${String(e)}`);
|
|
707
498
|
}
|
|
708
499
|
async function resolveNpmProvider(spec, options = {}) {
|
|
@@ -723,10 +514,10 @@ async function resolveNpmProvider(spec, options = {}) {
|
|
|
723
514
|
await ensureNpmPackageInstalled(packageName, { version, cwd });
|
|
724
515
|
await load();
|
|
725
516
|
} catch (installErr) {
|
|
726
|
-
throw
|
|
517
|
+
throw normalizeError2(installErr, `agent-llm: failed to install or load npm provider "${packageName}"`);
|
|
727
518
|
}
|
|
728
519
|
} else {
|
|
729
|
-
throw
|
|
520
|
+
throw normalizeError2(err, `agent-llm: failed to load npm provider "${packageName}"`);
|
|
730
521
|
}
|
|
731
522
|
}
|
|
732
523
|
if (fragmentProvider && installNpmIfMissing && !getChatModelFactory(fragmentProvider)) {
|
|
@@ -734,7 +525,7 @@ async function resolveNpmProvider(spec, options = {}) {
|
|
|
734
525
|
await ensureNpmPackageInstalled(packageName, { version, cwd });
|
|
735
526
|
await load();
|
|
736
527
|
} catch (installErr) {
|
|
737
|
-
throw
|
|
528
|
+
throw normalizeError2(installErr, `agent-llm: failed to install or load npm provider "${packageName}" (provider "${fragmentProvider}" not registered)`);
|
|
738
529
|
}
|
|
739
530
|
if (!getChatModelFactory(fragmentProvider)) {
|
|
740
531
|
throw new Error(`agent-llm: package "${packageName}" was installed but did not register provider "${fragmentProvider}". Check that the package exports getLLMExtension() or registerLLMExtension().`);
|
|
@@ -763,7 +554,7 @@ async function resolveLlmSectionWithNpm(llmSection, options = {}) {
|
|
|
763
554
|
try {
|
|
764
555
|
out.push(await resolveLlmSectionWithNpm(llmSection[i], options));
|
|
765
556
|
} catch (e) {
|
|
766
|
-
throw
|
|
557
|
+
throw normalizeError2(e, `agent-llm: failed to resolve llm section at index ${i}`);
|
|
767
558
|
}
|
|
768
559
|
}
|
|
769
560
|
return out;
|
|
@@ -776,14 +567,14 @@ async function resolveLlmSectionWithNpm(llmSection, options = {}) {
|
|
|
776
567
|
const resolved = await resolveNpmProvider(v, options);
|
|
777
568
|
out[k] = resolved ?? v;
|
|
778
569
|
} catch (e) {
|
|
779
|
-
throw
|
|
570
|
+
throw normalizeError2(e, `agent-llm: failed to resolve provider "${String(v)}"`);
|
|
780
571
|
}
|
|
781
572
|
continue;
|
|
782
573
|
}
|
|
783
574
|
try {
|
|
784
575
|
out[k] = await resolveLlmSectionWithNpm(v, options);
|
|
785
576
|
} catch (e) {
|
|
786
|
-
throw
|
|
577
|
+
throw normalizeError2(e, `agent-llm: failed to resolve llm section key "${k}"`);
|
|
787
578
|
}
|
|
788
579
|
}
|
|
789
580
|
return out;
|
|
@@ -802,20 +593,75 @@ async function createChatModelFromLlmConfigWithNpm(options) {
|
|
|
802
593
|
llmSection: resolvedSection
|
|
803
594
|
});
|
|
804
595
|
} catch (e) {
|
|
805
|
-
throw
|
|
596
|
+
throw normalizeError2(e, "agent-llm: createChatModelFromLlmConfigWithNpm failed");
|
|
806
597
|
}
|
|
807
598
|
}
|
|
808
599
|
|
|
809
600
|
// src/connectivity/check.ts
|
|
601
|
+
import https from "https";
|
|
810
602
|
var DEFAULT_TIMEOUT_MS = 8e3;
|
|
811
|
-
function
|
|
603
|
+
function probePath(baseURL) {
|
|
812
604
|
const base = baseURL.replace(/\/+$/, "");
|
|
813
605
|
if (base.endsWith("/v1")) return `${base}/models`;
|
|
814
606
|
return base.includes("/v1") ? `${base}/models` : `${base}/v1/models`;
|
|
815
607
|
}
|
|
608
|
+
function resolveProbeRequest(baseURL, endpointOptions) {
|
|
609
|
+
let path = probePath(baseURL);
|
|
610
|
+
const urlObj = new URL(path);
|
|
611
|
+
const resolveFrom = endpointOptions?.resolveHost?.from;
|
|
612
|
+
const resolveTo = endpointOptions?.resolveHost?.to;
|
|
613
|
+
let hostHeader = endpointOptions?.host;
|
|
614
|
+
if (resolveFrom && resolveTo && urlObj.hostname) {
|
|
615
|
+
urlObj.hostname = urlObj.hostname.replace(resolveFrom, resolveTo);
|
|
616
|
+
hostHeader = hostHeader ?? resolveFrom;
|
|
617
|
+
}
|
|
618
|
+
const searchParams = new URLSearchParams(urlObj.search);
|
|
619
|
+
if (endpointOptions?.bypassAuth === true) searchParams.set("bypass_auth", "true");
|
|
620
|
+
urlObj.search = searchParams.toString();
|
|
621
|
+
return { url: urlObj.toString(), hostHeader };
|
|
622
|
+
}
|
|
623
|
+
function checkWithHttps(url, hostHeader, options) {
|
|
624
|
+
return new Promise((resolve) => {
|
|
625
|
+
const u = new URL(url);
|
|
626
|
+
const reqOpts = {
|
|
627
|
+
hostname: u.hostname,
|
|
628
|
+
port: u.port || (u.protocol === "https:" ? 443 : 80),
|
|
629
|
+
path: u.pathname + u.search,
|
|
630
|
+
method: "GET",
|
|
631
|
+
headers: { Accept: "application/json" },
|
|
632
|
+
rejectUnauthorized: options.verifySSL
|
|
633
|
+
};
|
|
634
|
+
if (hostHeader) reqOpts.headers = { ...reqOpts.headers, Host: hostHeader };
|
|
635
|
+
const timeoutId = setTimeout(() => {
|
|
636
|
+
req.destroy();
|
|
637
|
+
resolve({ reachable: false, message: "Connection timed out" });
|
|
638
|
+
}, options.timeoutMs);
|
|
639
|
+
const req = https.request(reqOpts, (res) => {
|
|
640
|
+
clearTimeout(timeoutId);
|
|
641
|
+
resolve({
|
|
642
|
+
reachable: true,
|
|
643
|
+
message: res.statusCode === 200 ? "OK" : `HTTP ${res.statusCode}`,
|
|
644
|
+
statusCode: res.statusCode
|
|
645
|
+
});
|
|
646
|
+
});
|
|
647
|
+
req.on("error", (err) => {
|
|
648
|
+
clearTimeout(timeoutId);
|
|
649
|
+
resolve({ reachable: false, message: err.message || "Connection failed" });
|
|
650
|
+
});
|
|
651
|
+
req.end();
|
|
652
|
+
});
|
|
653
|
+
}
|
|
816
654
|
async function checkEndpointConnectivity(baseURL, options) {
|
|
817
655
|
const timeoutMs = options?.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
818
|
-
const
|
|
656
|
+
const useHttps = options?.resolveHost != null || options?.verifySSL === false || options?.host != null || options?.bypassAuth === true;
|
|
657
|
+
if (useHttps) {
|
|
658
|
+
const { url: url2, hostHeader } = resolveProbeRequest(baseURL, options);
|
|
659
|
+
return checkWithHttps(url2, hostHeader, {
|
|
660
|
+
timeoutMs,
|
|
661
|
+
verifySSL: options?.verifySSL === true
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
const url = probePath(baseURL);
|
|
819
665
|
const controller = new AbortController();
|
|
820
666
|
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
821
667
|
try {
|
|
@@ -852,16 +698,36 @@ function buildUnreachableError(endpointId, baseURL, detail) {
|
|
|
852
698
|
|
|
853
699
|
// src/api/create-agent-llm.ts
|
|
854
700
|
import { join as join2 } from "path";
|
|
701
|
+
var CIS_DEFAULT_RESOLVE_HOST = "s0010-ml-https.s0010.us-west-2.awswd";
|
|
702
|
+
var CIS_DEFAULT_RESOLVE_IP = "10.210.98.124";
|
|
703
|
+
function buildEndpointConnectivityOptions(config) {
|
|
704
|
+
const opts = config.options ?? config;
|
|
705
|
+
const provider = typeof config.provider === "string" ? config.provider : "";
|
|
706
|
+
const baseURL = config.baseURL;
|
|
707
|
+
const isCis = provider === "cis" || provider.includes("cis");
|
|
708
|
+
const useCisDefault = isCis && baseURL.includes(CIS_DEFAULT_RESOLVE_HOST) && opts?.resolveHost == null;
|
|
709
|
+
const resolveHost = opts?.resolveHost != null && typeof opts.resolveHost.from === "string" ? opts.resolveHost : useCisDefault ? { from: CIS_DEFAULT_RESOLVE_HOST, to: CIS_DEFAULT_RESOLVE_IP } : void 0;
|
|
710
|
+
const host = typeof opts?.host === "string" ? opts.host : resolveHost ? resolveHost.from : void 0;
|
|
711
|
+
if (resolveHost == null && host == null) return void 0;
|
|
712
|
+
const verifySSL = opts?.verifySSL === true;
|
|
713
|
+
const bypassAuth = opts?.bypassAuth !== false;
|
|
714
|
+
return {
|
|
715
|
+
resolveHost,
|
|
716
|
+
host,
|
|
717
|
+
verifySSL: resolveHost != null ? false : verifySSL ? true : void 0,
|
|
718
|
+
bypassAuth: bypassAuth ? true : void 0,
|
|
719
|
+
featureKey: typeof opts?.featureKey === "string" ? opts.featureKey : void 0
|
|
720
|
+
};
|
|
721
|
+
}
|
|
855
722
|
function resolveDefaultConfigPath() {
|
|
856
|
-
|
|
857
|
-
return join2(cwd, "llm.yaml");
|
|
723
|
+
return join2(process.cwd(), "llm.yaml");
|
|
858
724
|
}
|
|
859
|
-
function
|
|
725
|
+
function normalizeOptions(configPathOrOptions) {
|
|
860
726
|
if (configPathOrOptions == null) return {};
|
|
861
727
|
if (typeof configPathOrOptions === "string") return { configPath: configPathOrOptions };
|
|
862
728
|
return configPathOrOptions;
|
|
863
729
|
}
|
|
864
|
-
function
|
|
730
|
+
function normalizeError3(e, context) {
|
|
865
731
|
if (e instanceof Error) return new Error(`${context}: ${e.message}`, { cause: e });
|
|
866
732
|
return new Error(`${context}: ${String(e)}`);
|
|
867
733
|
}
|
|
@@ -870,16 +736,14 @@ async function ensureConnectivity(resolvedLlmSection, options) {
|
|
|
870
736
|
try {
|
|
871
737
|
const parsed = parseLlmSection(resolvedLlmSection ?? null);
|
|
872
738
|
configs = parsed.configs.filter(
|
|
873
|
-
(c) => typeof c.baseURL === "string" && c.baseURL.length > 0
|
|
739
|
+
(c) => typeof c.baseURL === "string" && c.baseURL.length > 0 && (c.baseURL.startsWith("http://") || c.baseURL.startsWith("https://")) && !c.baseURL.includes("${")
|
|
874
740
|
);
|
|
875
741
|
} catch {
|
|
876
742
|
return;
|
|
877
743
|
}
|
|
878
744
|
const shouldCheck = options.checkConnectivity !== false && configs.length > 0;
|
|
879
745
|
if (!shouldCheck) return;
|
|
880
|
-
const report = (status) =>
|
|
881
|
-
options.onConnectionStatus?.(status);
|
|
882
|
-
};
|
|
746
|
+
const report = (status) => options.onConnectionStatus?.(status);
|
|
883
747
|
const timeoutMs = options.connectivityTimeoutMs ?? 8e3;
|
|
884
748
|
for (const config of configs) {
|
|
885
749
|
const { id, baseURL } = config;
|
|
@@ -889,7 +753,11 @@ async function ensureConnectivity(resolvedLlmSection, options) {
|
|
|
889
753
|
baseURL,
|
|
890
754
|
message: "Checking CIS connection..."
|
|
891
755
|
});
|
|
892
|
-
const
|
|
756
|
+
const endpointOpts = buildEndpointConnectivityOptions(config);
|
|
757
|
+
const result = await checkEndpointConnectivity(baseURL, {
|
|
758
|
+
timeoutMs,
|
|
759
|
+
...endpointOpts
|
|
760
|
+
});
|
|
893
761
|
if (result.reachable) {
|
|
894
762
|
report({
|
|
895
763
|
phase: "reachable",
|
|
@@ -904,15 +772,13 @@ async function ensureConnectivity(resolvedLlmSection, options) {
|
|
|
904
772
|
baseURL,
|
|
905
773
|
message: result.message ?? "Unreachable"
|
|
906
774
|
});
|
|
907
|
-
throw new Error(
|
|
908
|
-
buildUnreachableError(id, baseURL, result.message)
|
|
909
|
-
);
|
|
775
|
+
throw new Error(buildUnreachableError(id, baseURL, result.message));
|
|
910
776
|
}
|
|
911
777
|
}
|
|
912
778
|
}
|
|
913
779
|
async function createAgentLlM(configPathOrOptions) {
|
|
914
780
|
try {
|
|
915
|
-
const options =
|
|
781
|
+
const options = normalizeOptions(configPathOrOptions);
|
|
916
782
|
const configPath = options.configPath ?? resolveDefaultConfigPath();
|
|
917
783
|
const llmSection = loadLlmConfig(configPath);
|
|
918
784
|
if (llmSection == null) {
|
|
@@ -931,7 +797,7 @@ async function createAgentLlM(configPathOrOptions) {
|
|
|
931
797
|
} catch (e) {
|
|
932
798
|
if (e instanceof Error && e.message.includes("No LLM config")) throw e;
|
|
933
799
|
if (e instanceof Error && e.message.includes("Cannot connect to CIS")) throw e;
|
|
934
|
-
throw
|
|
800
|
+
throw normalizeError3(e, "agent-llm: createAgentLlM failed");
|
|
935
801
|
}
|
|
936
802
|
}
|
|
937
803
|
|
|
@@ -940,14 +806,10 @@ export {
|
|
|
940
806
|
substituteEnv,
|
|
941
807
|
parseLlmYaml,
|
|
942
808
|
loadLlmConfig,
|
|
943
|
-
createOpenAIChatClient,
|
|
944
|
-
createOpenAIImageClient,
|
|
945
|
-
createOpenAIClient,
|
|
946
|
-
createClient,
|
|
947
|
-
registerProvider,
|
|
948
809
|
registerChatModelProvider,
|
|
949
810
|
getChatModelFactory,
|
|
950
811
|
createChatModelFromLlmConfig,
|
|
812
|
+
AGENT_LLM_PROVIDER_FIELD,
|
|
951
813
|
resolveLLMExtensionPackages,
|
|
952
814
|
discoverLLMExtensions,
|
|
953
815
|
loadLLMExtensions,
|
|
@@ -966,4 +828,4 @@ export {
|
|
|
966
828
|
buildUnreachableError,
|
|
967
829
|
createAgentLlM
|
|
968
830
|
};
|
|
969
|
-
//# sourceMappingURL=chunk-
|
|
831
|
+
//# sourceMappingURL=chunk-CWU7GNFB.js.map
|