@easynet/agent-llm 1.0.15 → 1.0.25

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.
Files changed (58) hide show
  1. package/dist/api/create-agent-llm.d.ts +4 -18
  2. package/dist/api/create-agent-llm.d.ts.map +1 -1
  3. package/dist/api/get-default-llm-config.d.ts +16 -0
  4. package/dist/api/get-default-llm-config.d.ts.map +1 -0
  5. package/dist/{chunk-AZDHRCIM.js → chunk-H4UQIDGT.js} +171 -338
  6. package/dist/chunk-H4UQIDGT.js.map +1 -0
  7. package/dist/cli/index.d.ts +0 -7
  8. package/dist/cli/index.d.ts.map +1 -1
  9. package/dist/cli/index.js +7 -12
  10. package/dist/cli/index.js.map +1 -1
  11. package/dist/cli/utils.d.ts +12 -0
  12. package/dist/cli/utils.d.ts.map +1 -0
  13. package/dist/config/index.d.ts +1 -3
  14. package/dist/config/index.d.ts.map +1 -1
  15. package/dist/config/loader.d.ts +0 -14
  16. package/dist/config/loader.d.ts.map +1 -1
  17. package/dist/config/parser.d.ts +0 -3
  18. package/dist/config/parser.d.ts.map +1 -1
  19. package/dist/config/yaml.d.ts +9 -0
  20. package/dist/config/yaml.d.ts.map +1 -0
  21. package/dist/connectivity/check.d.ts +0 -23
  22. package/dist/connectivity/check.d.ts.map +1 -1
  23. package/dist/connectivity/index.d.ts +2 -4
  24. package/dist/connectivity/index.d.ts.map +1 -1
  25. package/dist/connectivity/types.d.ts +0 -11
  26. package/dist/connectivity/types.d.ts.map +1 -1
  27. package/dist/extensions/index.d.ts +3 -3
  28. package/dist/extensions/index.d.ts.map +1 -1
  29. package/dist/extensions/loader.d.ts +1 -17
  30. package/dist/extensions/loader.d.ts.map +1 -1
  31. package/dist/extensions/npm-protocol.d.ts +7 -33
  32. package/dist/extensions/npm-protocol.d.ts.map +1 -1
  33. package/dist/index.d.ts +18 -13
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +56 -38
  36. package/dist/index.js.map +1 -1
  37. package/dist/langchain/index.d.ts +13 -3
  38. package/dist/langchain/index.d.ts.map +1 -1
  39. package/dist/langchain/openai-compatible.d.ts +21 -0
  40. package/dist/langchain/openai-compatible.d.ts.map +1 -0
  41. package/dist/registry/chat-model.d.ts +1 -8
  42. package/dist/registry/chat-model.d.ts.map +1 -1
  43. package/dist/registry/index.d.ts +0 -5
  44. package/dist/registry/index.d.ts.map +1 -1
  45. package/dist/types.d.ts +12 -166
  46. package/dist/types.d.ts.map +1 -1
  47. package/dist/utils/deep-merge.d.ts +5 -0
  48. package/dist/utils/deep-merge.d.ts.map +1 -0
  49. package/package.json +11 -9
  50. package/dist/chunk-AZDHRCIM.js.map +0 -1
  51. package/dist/langchain/adapter.d.ts +0 -21
  52. package/dist/langchain/adapter.d.ts.map +0 -1
  53. package/dist/providers/index.d.ts +0 -7
  54. package/dist/providers/index.d.ts.map +0 -1
  55. package/dist/providers/openai.d.ts +0 -9
  56. package/dist/providers/openai.d.ts.map +0 -1
  57. package/dist/registry/client.d.ts +0 -13
  58. package/dist/registry/client.d.ts.map +0 -1
@@ -153,205 +153,29 @@ 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;
156
+ // src/langchain/openai-compatible.ts
157
+ import { ChatOpenAI } from "@langchain/openai";
158
+ function createChatOpenAI(options) {
159
+ const {
160
+ baseURL,
161
+ model,
162
+ temperature = 0,
163
+ apiKey,
164
+ defaultHeaders,
165
+ defaultQuery,
166
+ httpAgent
167
+ } = options;
168
+ const config = {};
169
+ if (baseURL) config.baseURL = baseURL;
170
+ if (defaultHeaders) config.defaultHeaders = defaultHeaders;
171
+ if (defaultQuery) config.defaultQuery = defaultQuery;
172
+ if (httpAgent) config.httpAgent = httpAgent;
173
+ return new ChatOpenAI({
174
+ model,
175
+ temperature,
176
+ ...apiKey ? { apiKey } : {},
177
+ ...Object.keys(config).length > 0 ? { configuration: config } : {}
178
+ });
355
179
  }
356
180
 
357
181
  // src/registry/chat-model.ts
@@ -363,14 +187,13 @@ function getChatModelFactory(providerName) {
363
187
  return CHAT_MODEL_FACTORIES.get(providerName.toLowerCase());
364
188
  }
365
189
 
366
- // src/langchain/adapter.ts
367
- import { ChatOpenAI } from "@langchain/openai";
190
+ // src/langchain/index.ts
368
191
  var DEFAULT_MODEL = "gpt-4o-mini";
369
- function normalizeAgentLlMError(e, context) {
192
+ function normalizeError(e, context) {
370
193
  if (e instanceof Error) return new Error(`${context}: ${e.message}`, { cause: e });
371
194
  return new Error(`${context}: ${String(e)}`);
372
195
  }
373
- function createChatModelFromLlmConfig(options) {
196
+ function createChatModelFromLlmConfig(options = {}) {
374
197
  const { llmSection, modelEnv, apiKeyEnv } = options;
375
198
  let defaultId;
376
199
  let configs;
@@ -379,61 +202,62 @@ function createChatModelFromLlmConfig(options) {
379
202
  defaultId = parsed.defaultId;
380
203
  configs = parsed.configs;
381
204
  } catch (e) {
382
- throw normalizeAgentLlMError(e, "agent-llm: failed to parse llm section");
205
+ throw normalizeError(e, "Failed to parse llm section");
383
206
  }
384
- const defaultConfig = configs.find((c) => c.id === defaultId) ?? configs[0];
385
- if (!defaultConfig) {
207
+ const config = configs.find((c) => c.id === defaultId) ?? configs[0];
208
+ if (!config) {
386
209
  const model2 = modelEnv ?? process.env.OPENAI_MODEL ?? DEFAULT_MODEL;
387
210
  const apiKey2 = apiKeyEnv ?? process.env.OPENAI_API_KEY;
388
- try {
389
- return new ChatOpenAI({
390
- model: model2,
391
- temperature: 0,
392
- ...apiKey2 ? { apiKey: apiKey2 } : {}
393
- });
394
- } catch (e) {
395
- throw normalizeAgentLlMError(e, "agent-llm: failed to create default ChatOpenAI");
396
- }
211
+ return createChatOpenAI({
212
+ model: model2,
213
+ temperature: 0,
214
+ ...apiKey2 ? { apiKey: apiKey2 } : {}
215
+ });
397
216
  }
398
- const provider = defaultConfig.provider ?? "openai";
399
- const chatModelFactory = getChatModelFactory(provider);
400
- if (chatModelFactory) {
401
- const config = {
402
- ...defaultConfig,
403
- model: modelEnv ?? defaultConfig.model,
404
- temperature: typeof defaultConfig.temperature === "number" ? defaultConfig.temperature : 0
405
- };
217
+ const provider = config.provider ?? "openai";
218
+ const factory = getChatModelFactory(provider);
219
+ if (factory) {
406
220
  try {
407
- return chatModelFactory(config);
221
+ return factory({
222
+ ...config,
223
+ model: modelEnv ?? config.model ?? DEFAULT_MODEL,
224
+ temperature: typeof config.temperature === "number" ? config.temperature : 0
225
+ });
408
226
  } catch (e) {
409
- throw normalizeAgentLlMError(e, `agent-llm: failed to create ChatModel for provider "${provider}"`);
227
+ throw normalizeError(e, `Failed to create ChatModel for provider "${provider}"`);
410
228
  }
411
229
  }
412
- const model = modelEnv ?? defaultConfig?.model ?? process.env.OPENAI_MODEL ?? DEFAULT_MODEL;
413
- let apiKey = apiKeyEnv ?? defaultConfig?.apiKey ?? process.env.OPENAI_API_KEY;
414
- let baseURL = defaultConfig?.baseURL;
230
+ const model = modelEnv ?? config.model ?? process.env.OPENAI_MODEL ?? DEFAULT_MODEL;
231
+ let apiKey = apiKeyEnv ?? config.apiKey ?? process.env.OPENAI_API_KEY;
232
+ let baseURL = config.baseURL;
415
233
  if (baseURL && !baseURL.replace(/\/$/, "").endsWith("/v1")) {
416
234
  baseURL = baseURL.replace(/\/$/, "") + "/v1";
417
235
  }
418
- if (baseURL && apiKey === void 0) {
419
- apiKey = "ollama";
236
+ if (baseURL && !apiKey) {
237
+ apiKey = "not-needed";
420
238
  }
421
- const temperature = typeof defaultConfig?.temperature === "number" ? defaultConfig.temperature : 0;
422
- const constructorOptions = {
239
+ const temperature = typeof config.temperature === "number" ? config.temperature : 0;
240
+ const opts = config.options;
241
+ const defaultHeaders = opts?.defaultHeaders;
242
+ const defaultQuery = opts?.defaultQuery;
243
+ const httpAgent = opts?.httpAgent;
244
+ return createChatOpenAI({
423
245
  model,
424
246
  temperature,
425
- ...apiKey ? { apiKey } : {},
426
- ...baseURL ? { configuration: { baseURL } } : {}
427
- };
428
- try {
429
- return new ChatOpenAI(constructorOptions);
430
- } catch (e) {
431
- throw normalizeAgentLlMError(e, "agent-llm: failed to create ChatOpenAI from config");
432
- }
247
+ baseURL,
248
+ apiKey,
249
+ defaultHeaders,
250
+ defaultQuery,
251
+ httpAgent
252
+ });
433
253
  }
434
254
 
255
+ // src/types.ts
256
+ var AGENT_LLM_PROVIDER_FIELD = "agentLlmProvider";
257
+
435
258
  // src/extensions/loader.ts
436
259
  import { readdirSync, readFileSync as readFileSync2, existsSync as existsSync2 } from "fs";
260
+ import { createRequire } from "module";
437
261
  import { join } from "path";
438
262
  import { pathToFileURL } from "url";
439
263
  var loadedPackages = /* @__PURE__ */ new Set();
@@ -442,12 +266,11 @@ function isLLMExtension(m) {
442
266
  const e = m;
443
267
  if (typeof e.providerName !== "string") return false;
444
268
  const hasRegister = typeof e.register === "function";
445
- const hasFactories = typeof e.createClient === "function" && typeof e.createChatModel === "function";
446
- return hasRegister || hasFactories;
269
+ const hasChatModel = typeof e.createChatModel === "function";
270
+ return hasRegister || hasChatModel;
447
271
  }
448
272
  function registerExtension(ext) {
449
- if (typeof ext.createClient === "function" && typeof ext.createChatModel === "function") {
450
- registerProvider(ext.providerName, ext.createClient);
273
+ if (typeof ext.createChatModel === "function") {
451
274
  registerChatModelProvider(ext.providerName, ext.createChatModel);
452
275
  return;
453
276
  }
@@ -476,7 +299,7 @@ function readPackageProviderName(pkgPath) {
476
299
  try {
477
300
  const raw = readFileSync2(pkgPath, "utf-8");
478
301
  const pkg = JSON.parse(raw);
479
- const declared = pkg.agentLlmProvider === true || Array.isArray(pkg.keywords) && pkg.keywords.includes("agent-llm-provider");
302
+ const declared = pkg[AGENT_LLM_PROVIDER_FIELD] === true || Array.isArray(pkg.keywords) && pkg.keywords.includes("agent-llm-provider");
480
303
  return declared && typeof pkg.name === "string" ? pkg.name : null;
481
304
  } catch {
482
305
  return null;
@@ -532,6 +355,17 @@ async function loadModuleFromPath(pkgDir) {
532
355
  entryUrl
533
356
  );
534
357
  }
358
+ function resolvePackageEntryFromCwd(pkg, cwd) {
359
+ const pkgDir = join(cwd, "node_modules", pkg);
360
+ const pkgJsonPath = join(pkgDir, "package.json");
361
+ if (!existsSync2(pkgJsonPath)) return null;
362
+ try {
363
+ const req = createRequire(pkgJsonPath);
364
+ return req.resolve(pkg);
365
+ } catch {
366
+ return null;
367
+ }
368
+ }
535
369
  async function loadLLMExtensions(extensionPackages, options) {
536
370
  const packages = Array.isArray(extensionPackages) ? extensionPackages.filter((p) => typeof p === "string" && String(p).trim().length > 0) : [];
537
371
  const cwd = options?.cwd ?? process.cwd();
@@ -568,6 +402,26 @@ async function loadLLMExtensions(extensionPackages, options) {
568
402
  }
569
403
  }
570
404
  if (loaded) continue;
405
+ const resolvedEntry = resolvePackageEntryFromCwd(pkg, cwd);
406
+ if (resolvedEntry) {
407
+ try {
408
+ const entryUrl = pathToFileURL(resolvedEntry).href;
409
+ const m = await import(
410
+ /* @vite-ignore */
411
+ entryUrl
412
+ );
413
+ const ext = getExtensionFromModule(m);
414
+ if (ext) {
415
+ registerExtension(ext);
416
+ continue;
417
+ }
418
+ if (typeof m.registerLLMExtension === "function") {
419
+ m.registerLLMExtension();
420
+ continue;
421
+ }
422
+ } catch {
423
+ }
424
+ }
571
425
  try {
572
426
  const m = await import(
573
427
  /* @vite-ignore */
@@ -599,7 +453,7 @@ async function loadDiscoveredExtensions(cwd = process.cwd()) {
599
453
  // src/extensions/npm-protocol.ts
600
454
  import { execFileSync } from "child_process";
601
455
  import { readFileSync as readFileSync3 } from "fs";
602
- import { createRequire } from "module";
456
+ import { createRequire as createRequire2 } from "module";
603
457
  var NPM_PROTOCOL_PREFIX = "npm:";
604
458
  var VERSION_LATEST = "latest";
605
459
  async function getLatestVersion(packageName, options = {}) {
@@ -615,12 +469,12 @@ async function getLatestVersion(packageName, options = {}) {
615
469
  return version;
616
470
  } catch (e) {
617
471
  const msg = e instanceof Error ? e.message : String(e);
618
- throw new Error(`agent-llm: failed to get latest version for "${packageName}": ${msg}`, { cause: e });
472
+ throw new Error(`Failed to get latest version for "${packageName}": ${msg}`, { cause: e });
619
473
  }
620
474
  }
621
475
  function getInstalledVersion(packageName, options = {}) {
622
476
  const cwd = options.cwd ?? process.cwd();
623
- const require2 = createRequire(import.meta.url);
477
+ const require2 = createRequire2(import.meta.url);
624
478
  try {
625
479
  const p = require2.resolve(`${packageName}/package.json`, { paths: [cwd] });
626
480
  const j = JSON.parse(readFileSync3(p, "utf-8"));
@@ -649,60 +503,36 @@ function isModuleNotFoundError(err) {
649
503
  return msg.includes("Cannot find module") || msg.includes("Cannot find package") || msg.includes("MODULE_NOT_FOUND") || msg.includes("ERR_MODULE_NOT_FOUND") || msg.includes("Failed to load url") || msg.includes("Does the file exist");
650
504
  }
651
505
  async function resolveInstallVersion(packageName, version, cwd) {
652
- if (version === void 0 || version === "" || version === VERSION_LATEST) {
506
+ const isLatestOrEmpty = version === void 0 || version === "" || typeof version === "string" && version.toLowerCase() === VERSION_LATEST;
507
+ if (isLatestOrEmpty) {
653
508
  return getLatestVersion(packageName, { cwd });
654
509
  }
655
510
  return version;
656
511
  }
657
512
  async function ensureNpmPackageInstalled(packageName, options = {}) {
658
513
  if (typeof packageName !== "string" || packageName.trim().length === 0) {
659
- throw new Error("agent-llm: ensureNpmPackageInstalled requires a non-empty package name");
514
+ throw new Error("ensureNpmPackageInstalled requires a non-empty package name");
660
515
  }
661
516
  const cwd = options.cwd ?? process.cwd();
662
- const requestedVersion = options.version;
663
- const resolvedVersion = await resolveInstallVersion(packageName, requestedVersion, cwd);
664
- try {
665
- await import(
666
- /* @vite-ignore */
667
- packageName
668
- );
669
- const askedForLatest = requestedVersion === void 0 || requestedVersion === "" || requestedVersion === VERSION_LATEST;
670
- if (askedForLatest && resolvedVersion !== void 0) {
671
- const installed = getInstalledVersion(packageName, { cwd });
672
- if (installed !== null && installed !== resolvedVersion) {
673
- const installSpec2 = `${packageName}@${resolvedVersion}`;
674
- try {
675
- execFileSync("npm", ["install", installSpec2], {
676
- cwd,
677
- stdio: "inherit",
678
- encoding: "utf-8"
679
- });
680
- } catch (e) {
681
- const msg = e instanceof Error ? e.message : String(e);
682
- throw new Error(`agent-llm: npm install failed for ${installSpec2}: ${msg}`, { cause: e });
683
- }
684
- }
517
+ const resolvedVersion = await resolveInstallVersion(packageName, options.version, cwd);
518
+ const installedVersion = getInstalledVersion(packageName, { cwd });
519
+ if (installedVersion !== resolvedVersion) {
520
+ const installSpec = `${packageName}@${resolvedVersion}`;
521
+ if (installedVersion === null) {
522
+ console.info(`[agent-llm] Installing provider: ${installSpec}`);
523
+ } else {
524
+ console.info(`[agent-llm] Updating provider: ${packageName} ${installedVersion} \u2192 ${resolvedVersion}`);
525
+ }
526
+ try {
527
+ execFileSync("npm", ["install", installSpec], { cwd, stdio: "inherit", encoding: "utf-8" });
528
+ } catch (e) {
529
+ const msg = e instanceof Error ? e.message : String(e);
530
+ throw new Error(`npm install failed for ${installSpec}: ${msg}`, { cause: e });
685
531
  }
686
- return;
687
- } catch (err) {
688
- if (!isModuleNotFoundError(err)) throw err;
689
- }
690
- const installSpec = resolvedVersion ? `${packageName}@${resolvedVersion}` : packageName;
691
- try {
692
- execFileSync("npm", ["install", installSpec], {
693
- cwd,
694
- stdio: "inherit",
695
- encoding: "utf-8"
696
- });
697
- } catch (e) {
698
- const msg = e instanceof Error ? e.message : String(e);
699
- throw new Error(`agent-llm: npm install failed for ${installSpec}: ${msg}`, { cause: e });
700
532
  }
701
533
  }
702
- function normalizeAgentLlMError2(e, context) {
703
- if (e instanceof Error) {
704
- return new Error(`${context}: ${e.message}`, { cause: e });
705
- }
534
+ function normalizeError2(e, context) {
535
+ if (e instanceof Error) return new Error(`${context}: ${e.message}`, { cause: e });
706
536
  return new Error(`${context}: ${String(e)}`);
707
537
  }
708
538
  async function resolveNpmProvider(spec, options = {}) {
@@ -715,6 +545,9 @@ async function resolveNpmProvider(spec, options = {}) {
715
545
  const load = async () => {
716
546
  await loadLLMExtensions([packageName], { cwd });
717
547
  };
548
+ if (installNpmIfMissing) {
549
+ await ensureNpmPackageInstalled(packageName, { version, cwd });
550
+ }
718
551
  try {
719
552
  await load();
720
553
  } catch (err) {
@@ -723,21 +556,19 @@ async function resolveNpmProvider(spec, options = {}) {
723
556
  await ensureNpmPackageInstalled(packageName, { version, cwd });
724
557
  await load();
725
558
  } catch (installErr) {
726
- throw normalizeAgentLlMError2(installErr, `agent-llm: failed to install or load npm provider "${packageName}"`);
559
+ throw normalizeError2(installErr, `Failed to install or load npm provider "${packageName}"`);
727
560
  }
728
561
  } else {
729
- throw normalizeAgentLlMError2(err, `agent-llm: failed to load npm provider "${packageName}"`);
562
+ throw normalizeError2(err, `Failed to load npm provider "${packageName}"`);
730
563
  }
731
564
  }
732
- if (fragmentProvider && installNpmIfMissing && !getChatModelFactory(fragmentProvider)) {
733
- try {
565
+ if (fragmentProvider && !getChatModelFactory(fragmentProvider)) {
566
+ if (installNpmIfMissing) {
734
567
  await ensureNpmPackageInstalled(packageName, { version, cwd });
735
568
  await load();
736
- } catch (installErr) {
737
- throw normalizeAgentLlMError2(installErr, `agent-llm: failed to install or load npm provider "${packageName}" (provider "${fragmentProvider}" not registered)`);
738
569
  }
739
570
  if (!getChatModelFactory(fragmentProvider)) {
740
- throw new Error(`agent-llm: package "${packageName}" was installed but did not register provider "${fragmentProvider}". Check that the package exports getLLMExtension() or registerLLMExtension().`);
571
+ throw new Error(`Package "${packageName}" was installed but did not register provider "${fragmentProvider}". Check that the package exports getLLMExtension() or registerLLMExtension().`);
741
572
  }
742
573
  }
743
574
  if (fragmentProvider) return fragmentProvider;
@@ -763,7 +594,7 @@ async function resolveLlmSectionWithNpm(llmSection, options = {}) {
763
594
  try {
764
595
  out.push(await resolveLlmSectionWithNpm(llmSection[i], options));
765
596
  } catch (e) {
766
- throw normalizeAgentLlMError2(e, `agent-llm: failed to resolve llm section at index ${i}`);
597
+ throw normalizeError2(e, `Failed to resolve llm section at index ${i}`);
767
598
  }
768
599
  }
769
600
  return out;
@@ -776,21 +607,21 @@ async function resolveLlmSectionWithNpm(llmSection, options = {}) {
776
607
  const resolved = await resolveNpmProvider(v, options);
777
608
  out[k] = resolved ?? v;
778
609
  } catch (e) {
779
- throw normalizeAgentLlMError2(e, `agent-llm: failed to resolve provider "${String(v)}"`);
610
+ throw normalizeError2(e, `Failed to resolve provider "${String(v)}"`);
780
611
  }
781
612
  continue;
782
613
  }
783
614
  try {
784
615
  out[k] = await resolveLlmSectionWithNpm(v, options);
785
616
  } catch (e) {
786
- throw normalizeAgentLlMError2(e, `agent-llm: failed to resolve llm section key "${k}"`);
617
+ throw normalizeError2(e, `Failed to resolve llm section key "${k}"`);
787
618
  }
788
619
  }
789
620
  return out;
790
621
  }
791
622
  return llmSection;
792
623
  }
793
- async function createChatModelFromLlmConfigWithNpm(options) {
624
+ async function createChatModelWithNpm(options = {}) {
794
625
  try {
795
626
  const { installNpmIfMissing, cwd, ...rest } = options;
796
627
  const resolvedSection = await resolveLlmSectionWithNpm(options.llmSection ?? null, {
@@ -802,7 +633,7 @@ async function createChatModelFromLlmConfigWithNpm(options) {
802
633
  llmSection: resolvedSection
803
634
  });
804
635
  } catch (e) {
805
- throw normalizeAgentLlMError2(e, "agent-llm: createChatModelFromLlmConfigWithNpm failed");
636
+ throw normalizeError2(e, "createChatModelWithNpm failed");
806
637
  }
807
638
  }
808
639
 
@@ -827,7 +658,7 @@ function resolveProbeRequest(baseURL, endpointOptions) {
827
658
  const searchParams = new URLSearchParams(urlObj.search);
828
659
  if (endpointOptions?.bypassAuth === true) searchParams.set("bypass_auth", "true");
829
660
  urlObj.search = searchParams.toString();
830
- return { url: urlObj.toString(), hostHeader, searchParams };
661
+ return { url: urlObj.toString(), hostHeader };
831
662
  }
832
663
  function checkWithHttps(url, hostHeader, options) {
833
664
  return new Promise((resolve) => {
@@ -843,10 +674,7 @@ function checkWithHttps(url, hostHeader, options) {
843
674
  if (hostHeader) reqOpts.headers = { ...reqOpts.headers, Host: hostHeader };
844
675
  const timeoutId = setTimeout(() => {
845
676
  req.destroy();
846
- resolve({
847
- reachable: false,
848
- message: "Connection timed out"
849
- });
677
+ resolve({ reachable: false, message: "Connection timed out" });
850
678
  }, options.timeoutMs);
851
679
  const req = https.request(reqOpts, (res) => {
852
680
  clearTimeout(timeoutId);
@@ -858,10 +686,7 @@ function checkWithHttps(url, hostHeader, options) {
858
686
  });
859
687
  req.on("error", (err) => {
860
688
  clearTimeout(timeoutId);
861
- resolve({
862
- reachable: false,
863
- message: err.message || "Connection failed"
864
- });
689
+ resolve({ reachable: false, message: err.message || "Connection failed" });
865
690
  });
866
691
  req.end();
867
692
  });
@@ -926,25 +751,23 @@ function buildEndpointConnectivityOptions(config) {
926
751
  if (resolveHost == null && host == null) return void 0;
927
752
  const verifySSL = opts?.verifySSL === true;
928
753
  const bypassAuth = opts?.bypassAuth !== false;
929
- const featureKey = typeof opts?.featureKey === "string" ? opts.featureKey : void 0;
930
754
  return {
931
755
  resolveHost,
932
756
  host,
933
757
  verifySSL: resolveHost != null ? false : verifySSL ? true : void 0,
934
758
  bypassAuth: bypassAuth ? true : void 0,
935
- featureKey
759
+ featureKey: typeof opts?.featureKey === "string" ? opts.featureKey : void 0
936
760
  };
937
761
  }
938
762
  function resolveDefaultConfigPath() {
939
- const cwd = process.cwd();
940
- return join2(cwd, "llm.yaml");
763
+ return join2(process.cwd(), "llm.yaml");
941
764
  }
942
- function normalizeCreateOptions(configPathOrOptions) {
765
+ function normalizeOptions(configPathOrOptions) {
943
766
  if (configPathOrOptions == null) return {};
944
767
  if (typeof configPathOrOptions === "string") return { configPath: configPathOrOptions };
945
768
  return configPathOrOptions;
946
769
  }
947
- function normalizeAgentLlMError3(e, context) {
770
+ function normalizeError3(e, context) {
948
771
  if (e instanceof Error) return new Error(`${context}: ${e.message}`, { cause: e });
949
772
  return new Error(`${context}: ${String(e)}`);
950
773
  }
@@ -953,16 +776,14 @@ async function ensureConnectivity(resolvedLlmSection, options) {
953
776
  try {
954
777
  const parsed = parseLlmSection(resolvedLlmSection ?? null);
955
778
  configs = parsed.configs.filter(
956
- (c) => typeof c.baseURL === "string" && c.baseURL.length > 0
779
+ (c) => typeof c.baseURL === "string" && c.baseURL.length > 0 && (c.baseURL.startsWith("http://") || c.baseURL.startsWith("https://")) && !c.baseURL.includes("${")
957
780
  );
958
781
  } catch {
959
782
  return;
960
783
  }
961
784
  const shouldCheck = options.checkConnectivity !== false && configs.length > 0;
962
785
  if (!shouldCheck) return;
963
- const report = (status) => {
964
- options.onConnectionStatus?.(status);
965
- };
786
+ const report = (status) => options.onConnectionStatus?.(status);
966
787
  const timeoutMs = options.connectivityTimeoutMs ?? 8e3;
967
788
  for (const config of configs) {
968
789
  const { id, baseURL } = config;
@@ -970,7 +791,7 @@ async function ensureConnectivity(resolvedLlmSection, options) {
970
791
  phase: "checking",
971
792
  endpointId: id,
972
793
  baseURL,
973
- message: "Checking CIS connection..."
794
+ message: "Checking connection..."
974
795
  });
975
796
  const endpointOpts = buildEndpointConnectivityOptions(config);
976
797
  const result = await checkEndpointConnectivity(baseURL, {
@@ -991,19 +812,19 @@ async function ensureConnectivity(resolvedLlmSection, options) {
991
812
  baseURL,
992
813
  message: result.message ?? "Unreachable"
993
814
  });
994
- throw new Error(
995
- buildUnreachableError(id, baseURL, result.message)
996
- );
815
+ throw new Error(buildUnreachableError(id, baseURL, result.message));
997
816
  }
998
817
  }
999
818
  }
1000
819
  async function createAgentLlM(configPathOrOptions) {
1001
820
  try {
1002
- const options = normalizeCreateOptions(configPathOrOptions);
821
+ const options = normalizeOptions(configPathOrOptions);
1003
822
  const configPath = options.configPath ?? resolveDefaultConfigPath();
1004
823
  const llmSection = loadLlmConfig(configPath);
1005
824
  if (llmSection == null) {
1006
- throw new Error(`No LLM config at ${configPath}. Add llm.yaml in the current directory, or pass configPath.`);
825
+ throw new Error(
826
+ `No LLM config at ${configPath}. Add llm.yaml in the current directory, or pass configPath.`
827
+ );
1007
828
  }
1008
829
  const resolvedSection = await resolveLlmSectionWithNpm(llmSection, {
1009
830
  installNpmIfMissing: options.installNpmIfMissing !== false,
@@ -1017,9 +838,22 @@ async function createAgentLlM(configPathOrOptions) {
1017
838
  return createChatModelFromLlmConfig({ llmSection: resolvedSection });
1018
839
  } catch (e) {
1019
840
  if (e instanceof Error && e.message.includes("No LLM config")) throw e;
1020
- if (e instanceof Error && e.message.includes("Cannot connect to CIS")) throw e;
1021
- throw normalizeAgentLlMError3(e, "agent-llm: createAgentLlM failed");
841
+ if (e instanceof Error && e.message.includes("Cannot connect to")) throw e;
842
+ throw normalizeError3(e, "createAgentLlM failed");
843
+ }
844
+ }
845
+
846
+ // src/cli/utils.ts
847
+ function messageContentToString(content) {
848
+ if (typeof content === "string") return content;
849
+ if (Array.isArray(content)) {
850
+ return content.map((c) => "text" in c && c.text ? c.text : "").join("");
1022
851
  }
852
+ return String(content ?? "");
853
+ }
854
+ function exitWithError(err, code = 1) {
855
+ console.error("Error:", err instanceof Error ? err.message : String(err));
856
+ process.exit(code);
1023
857
  }
1024
858
 
1025
859
  export {
@@ -1027,14 +861,11 @@ export {
1027
861
  substituteEnv,
1028
862
  parseLlmYaml,
1029
863
  loadLlmConfig,
1030
- createOpenAIChatClient,
1031
- createOpenAIImageClient,
1032
- createOpenAIClient,
1033
- createClient,
1034
- registerProvider,
864
+ createChatOpenAI,
1035
865
  registerChatModelProvider,
1036
866
  getChatModelFactory,
1037
867
  createChatModelFromLlmConfig,
868
+ AGENT_LLM_PROVIDER_FIELD,
1038
869
  resolveLLMExtensionPackages,
1039
870
  discoverLLMExtensions,
1040
871
  loadLLMExtensions,
@@ -1047,10 +878,12 @@ export {
1047
878
  ensureNpmPackageInstalled,
1048
879
  resolveNpmProvider,
1049
880
  resolveLlmSectionWithNpm,
1050
- createChatModelFromLlmConfigWithNpm,
881
+ createChatModelWithNpm,
1051
882
  checkEndpointConnectivity,
1052
883
  CIS_UNREACHABLE_REMINDER,
1053
884
  buildUnreachableError,
1054
- createAgentLlM
885
+ createAgentLlM,
886
+ messageContentToString,
887
+ exitWithError
1055
888
  };
1056
- //# sourceMappingURL=chunk-AZDHRCIM.js.map
889
+ //# sourceMappingURL=chunk-H4UQIDGT.js.map