@easynet/agent-llm 1.0.10 → 1.0.12

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 (48) hide show
  1. package/README.md +48 -60
  2. package/dist/{createAgentLlM.d.ts → api/create-agent-llm.d.ts} +2 -2
  3. package/dist/api/create-agent-llm.d.ts.map +1 -0
  4. package/dist/{chunk-L3K6IEC6.js → chunk-VR7BRFGB.js} +134 -134
  5. package/dist/chunk-VR7BRFGB.js.map +1 -0
  6. package/dist/{cli.d.ts → cli/index.d.ts} +1 -1
  7. package/dist/cli/index.d.ts.map +1 -0
  8. package/dist/{cli.js → cli/index.js} +5 -5
  9. package/dist/cli/index.js.map +1 -0
  10. package/dist/config/index.d.ts +7 -0
  11. package/dist/config/index.d.ts.map +1 -0
  12. package/dist/{loadLlmConfig.d.ts → config/loader.d.ts} +1 -1
  13. package/dist/config/loader.d.ts.map +1 -0
  14. package/dist/{config.d.ts → config/parser.d.ts} +2 -2
  15. package/dist/config/parser.d.ts.map +1 -0
  16. package/dist/extensions/index.d.ts +8 -0
  17. package/dist/extensions/index.d.ts.map +1 -0
  18. package/dist/{loadLLMExtensions.d.ts → extensions/loader.d.ts} +1 -1
  19. package/dist/extensions/loader.d.ts.map +1 -0
  20. package/dist/{npmProviderProtocol.d.ts → extensions/npm-protocol.d.ts} +3 -3
  21. package/dist/{npmProviderProtocol.d.ts.map → extensions/npm-protocol.d.ts.map} +1 -1
  22. package/dist/index.d.ts +13 -13
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +2 -2
  25. package/dist/index.js.map +1 -1
  26. package/dist/{llmAdapter.d.ts → langchain/adapter.d.ts} +1 -1
  27. package/dist/langchain/adapter.d.ts.map +1 -0
  28. package/dist/langchain/index.d.ts +6 -0
  29. package/dist/langchain/index.d.ts.map +1 -0
  30. package/dist/{chatModelRegistry.d.ts → registry/chat-model.d.ts} +2 -2
  31. package/dist/registry/chat-model.d.ts.map +1 -0
  32. package/dist/{factory.d.ts → registry/client.d.ts} +2 -2
  33. package/dist/registry/client.d.ts.map +1 -0
  34. package/dist/registry/index.d.ts +8 -0
  35. package/dist/registry/index.d.ts.map +1 -0
  36. package/dist/types.d.ts +1 -1
  37. package/dist/types.d.ts.map +1 -1
  38. package/package.json +3 -3
  39. package/dist/chatModelRegistry.d.ts.map +0 -1
  40. package/dist/chunk-L3K6IEC6.js.map +0 -1
  41. package/dist/cli.d.ts.map +0 -1
  42. package/dist/cli.js.map +0 -1
  43. package/dist/config.d.ts.map +0 -1
  44. package/dist/createAgentLlM.d.ts.map +0 -1
  45. package/dist/factory.d.ts.map +0 -1
  46. package/dist/llmAdapter.d.ts.map +0 -1
  47. package/dist/loadLLMExtensions.d.ts.map +0 -1
  48. package/dist/loadLlmConfig.d.ts.map +0 -1
package/README.md CHANGED
@@ -1,42 +1,64 @@
1
1
  # @easynet/agent-llm
2
2
 
3
- Load an LLM from **llm.yaml** (or your config) and use it from the command line or in a LangChain agent. Supports OpenAI and OpenAI-compatible endpoints (Ollama, Groq, Azure, etc.).
3
+ Load an LLM from **llm.yaml** for CLI or LangChain. Releases are automated via semantic-release on push to `master`.
4
4
 
5
- ## Command line
5
+ **Extensible:** define your own extension (implement `ILLMExtension`).
6
6
 
7
- Install and run with a question:
7
+ ---
8
+
9
+ ## Quick start
10
+
11
+ **1.** Add `llm.yaml` in your project root:
12
+
13
+ ```yaml
14
+ llm:
15
+ default: small
16
+ strong:
17
+ provider: npm:@scope/package-name@latest#provider-name
18
+ base_url: https://your-api.example.com
19
+ model: your-model
20
+ small:
21
+ provider: openai
22
+ base_url: http://localhost:11434/v1
23
+ model: qwen3:0.6b
24
+ ```
25
+
26
+ **2.** Run:
8
27
 
9
28
  ```bash
10
- npx @easynet/agent-llm "hi"
11
- npx @easynet/agent-llm "What is 10 + 20?"
29
+ npx @easynet/agent-llm "your prompt"
12
30
  ```
13
31
 
14
- Config is read from **llm.yaml** in the current directory. See [config/llm.yaml.example](config/llm.yaml.example). Placeholders like `${OPENAI_API_KEY}` are replaced from the environment.
32
+ ---
15
33
 
16
- ## Use in a LangChain agent
34
+ ## LangChain agent
17
35
 
18
- **1.** Get the LLM from config with `createAgentLlM()` (async; resolves npm: providers):
36
+ 1. **Get the LLM** (async; resolves `npm:` providers and installs packages if needed):
19
37
 
20
38
  ```ts
21
39
  import { createAgentLlM } from "@easynet/agent-llm";
22
- import { createAgent, tool } from "langchain";
23
- import { z } from "zod";
24
40
 
25
41
  const llm = await createAgentLlM();
26
42
  ```
27
43
 
28
- **2.** Create your agent with LangChains `createAgent` and your tools:
44
+ 2. **Build the agent** with LangChain's `createAgent` and tools:
29
45
 
30
46
  ```ts
47
+ import { createAgent, tool } from "langchain";
48
+ import { z } from "zod";
49
+
31
50
  const add = tool(
32
51
  (input: { a: number; b: number }) => String(input.a + input.b),
33
52
  { name: "add", description: "Add two numbers.", schema: z.object({ a: z.number(), b: z.number() }) }
34
53
  );
35
54
 
36
- const agent = createAgent({ model: llm as unknown as Parameters<typeof createAgent>[0]["model"], tools: [add] });
55
+ const agent = createAgent({
56
+ model: llm as unknown as Parameters<typeof createAgent>[0]["model"],
57
+ tools: [add],
58
+ });
37
59
  ```
38
60
 
39
- **3.** Invoke with messages:
61
+ 3. **Invoke** with messages:
40
62
 
41
63
  ```ts
42
64
  import { HumanMessage } from "@langchain/core/messages";
@@ -45,59 +67,25 @@ const result = await agent.invoke({ messages: [new HumanMessage("What is 10 + 20
45
67
  console.log(result.messages?.slice(-1)[0]?.content);
46
68
  ```
47
69
 
48
- Full example: [examples/langchain-react-agent.ts](examples/langchain-react-agent.ts).
49
-
50
- ## Config
70
+ Full runnable example: [examples/langchain-react-agent.ts](examples/langchain-react-agent.ts).
51
71
 
52
- Put **llm.yaml** in your project (current directory). Example:
53
-
54
- ```yaml
55
- provider: openai
56
- model: gpt-4o-mini
57
- temperature: 0
58
- apiKey: ${OPENAI_API_KEY}
59
- # baseURL: https://api.openai.com/v1 # or Ollama, Groq, etc.
60
- ```
72
+ ---
61
73
 
62
- Optional: pass a path — `createAgentLlM("path/to/llm.yaml")` or `createAgentLlM({ configPath: "/path/to/llm.yaml" })`.
74
+ ## npm provider protocol
63
75
 
64
- ## npm: protocol in provider (install on demand)
76
+ Use a provider from an **npm package**. If the package is missing, the framework can install it and then load the provider.
65
77
 
66
- You can set the provider by **npm package name** (and optional version) in config. If the package is not installed, the framework will **install it** and then use it as the provider.
78
+ Example in a named entry:
67
79
 
68
- **Recommended format:** `npm:<package>@<version>#<provider>` — e.g. **`provider: "npm:wallee-llm@0.1.0#cis"`**.
69
-
70
- - **`provider: "npm:wallee-llm@0.1.0#cis"`** – **(recommended)** install `wallee-llm@0.1.0` if missing, then use provider `cis`.
71
- - **`provider: "npm:wallee-llm@0.1.0"`** – use a specific version; default provider is used.
72
- - **`provider: "npm:wallee-llm#cis"`** – load wallee-llm and use the provider named `cis`.
73
- - **`provider: "npm:wallee-llm"`** – load wallee-llm and use its default provider (e.g. `cis`).
74
-
75
- **createAgentLlM()** resolves npm: providers (and optionally installs packages) when reading config. For a raw llm section use **createChatModelFromLlmConfigWithNpm**:
76
-
77
- ```ts
78
- import { createChatModelFromLlmConfigWithNpm, createAgentLlM } from "@easynet/agent-llm";
79
-
80
- // From a raw llm section (e.g. from loadLlmConfig)
81
- const model = await createChatModelFromLlmConfigWithNpm({ llmSection });
82
-
83
- // From llm.yaml in the current directory
84
- const llm = await createAgentLlM();
85
- // Or with a path: createAgentLlM("path/to/llm.yaml")
80
+ ```yaml
81
+ strong:
82
+ provider: "npm:@scope/package-name@latest#provider-name"
83
+ base_url: https://your-api.example.com
84
+ model: your-model
86
85
  ```
87
86
 
88
- Options: **installNpmIfMissing** (default `true`) and **cwd** (default `process.cwd()` for npm install). Exports: `parseNpmProviderSpec`, `ensureNpmPackageInstalled`, `resolveNpmProvider`, `resolveLlmSectionWithNpm`, `isNpmProviderSpec`, `createChatModelFromLlmConfigWithNpm`, `createAgentLlM`.
89
-
90
- ## Using with Workday Artifactory
87
+ ---
91
88
 
92
- If **@easynet/agent-llm** is installed from Artifactory but your default registry is **npm-sandbox**, npm may 404 when resolving dependencies (@langchain/core, axios, openai, etc.). Use an **.npmrc** so the default registry is public npm and only **@easynet** comes from Artifactory:
93
-
94
- ```ini
95
- registry=https://registry.npmjs.org/
96
- @easynet:registry=https://artifactory.workday.com/artifactory/api/npm/npm-virtual/
97
- ```
89
+ ## License
98
90
 
99
- Copy from [.npmrc.example](.npmrc.example) into your project (e.g. `/tmp/test`) or home `~/.npmrc`, then run:
100
-
101
- ```bash
102
- npx @easynet/agent-llm hi
103
- ```
91
+ MIT · [GitHub](https://github.com/easynet-world/agent-llm)
@@ -1,4 +1,4 @@
1
- import { createChatModelFromLlmConfig } from "./llmAdapter.js";
1
+ import { createChatModelFromLlmConfig } from "../langchain/adapter.js";
2
2
  export interface CreateAgentLlMOptions {
3
3
  /** Path to YAML config file. If omitted, uses llm.yaml in the current directory (cwd). */
4
4
  configPath?: string;
@@ -12,4 +12,4 @@ export interface CreateAgentLlMOptions {
12
12
  * - createAgentLlM({ configPath: "...", installNpmIfMissing: true }) — options object
13
13
  */
14
14
  export declare function createAgentLlM(configPathOrOptions?: string | CreateAgentLlMOptions): Promise<ReturnType<typeof createChatModelFromLlmConfig>>;
15
- //# sourceMappingURL=createAgentLlM.d.ts.map
15
+ //# sourceMappingURL=create-agent-llm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-agent-llm.d.ts","sourceRoot":"","sources":["../../src/api/create-agent-llm.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAC;AAIvE,MAAM,WAAW,qBAAqB;IACpC,0FAA0F;IAC1F,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kGAAkG;IAClG,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAgDD;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,mBAAmB,CAAC,EAAE,MAAM,GAAG,qBAAqB,GACnD,OAAO,CAAC,UAAU,CAAC,OAAO,4BAA4B,CAAC,CAAC,CAiB1D"}
@@ -1,4 +1,4 @@
1
- // src/config.ts
1
+ // src/config/parser.ts
2
2
  var DEFAULT_LLM_ID = "default";
3
3
  var RESERVED_KEYS = /* @__PURE__ */ new Set([
4
4
  "default",
@@ -108,81 +108,48 @@ function normalizeLlmConfig(o) {
108
108
  return config;
109
109
  }
110
110
 
111
- // src/chatModelRegistry.ts
112
- var CHAT_MODEL_FACTORIES = /* @__PURE__ */ new Map();
113
- function registerChatModelProvider(providerName, factory) {
114
- CHAT_MODEL_FACTORIES.set(providerName.toLowerCase(), factory);
115
- }
116
- function getChatModelFactory(providerName) {
117
- return CHAT_MODEL_FACTORIES.get(providerName.toLowerCase());
111
+ // src/config/loader.ts
112
+ import { readFileSync, existsSync } from "fs";
113
+ import { parse as parseYaml } from "yaml";
114
+ function substituteEnv(obj) {
115
+ if (obj === null || obj === void 0) return obj;
116
+ if (typeof obj === "string") {
117
+ const m = obj.match(/^\$\{(\w+)\}$/);
118
+ return m ? process.env[m[1]] ?? obj : obj;
119
+ }
120
+ if (Array.isArray(obj)) return obj.map(substituteEnv);
121
+ if (typeof obj === "object") {
122
+ const out = {};
123
+ for (const [k, v] of Object.entries(obj)) out[k] = substituteEnv(v);
124
+ return out;
125
+ }
126
+ return obj;
118
127
  }
119
-
120
- // src/llmAdapter.ts
121
- import { ChatOpenAI } from "@langchain/openai";
122
- var DEFAULT_MODEL = "gpt-4o-mini";
123
- function normalizeAgentLlMError(e, context) {
124
- if (e instanceof Error) return new Error(`${context}: ${e.message}`, { cause: e });
125
- return new Error(`${context}: ${String(e)}`);
128
+ function parseLlmYaml(content, options = {}) {
129
+ const { substituteEnv: doSub = true } = options;
130
+ const parsed = parseYaml(content);
131
+ const llm = parsed?.llm;
132
+ if (llm == null) return void 0;
133
+ return doSub ? substituteEnv(llm) : llm;
126
134
  }
127
- function createChatModelFromLlmConfig(options) {
128
- const { llmSection, modelEnv, apiKeyEnv } = options;
129
- let defaultId;
130
- let configs;
135
+ function loadLlmConfig(filePath, options = {}) {
136
+ if (typeof filePath !== "string" || filePath.trim().length === 0) {
137
+ throw new Error("agent-llm: loadLlmConfig requires a non-empty file path");
138
+ }
139
+ if (!existsSync(filePath)) return null;
140
+ let raw;
131
141
  try {
132
- const parsed = parseLlmSection(llmSection ?? null);
133
- defaultId = parsed.defaultId;
134
- configs = parsed.configs;
142
+ raw = readFileSync(filePath, "utf8");
135
143
  } catch (e) {
136
- throw normalizeAgentLlMError(e, "agent-llm: failed to parse llm section");
137
- }
138
- const defaultConfig = configs.find((c) => c.id === defaultId) ?? configs[0];
139
- if (!defaultConfig) {
140
- const model2 = modelEnv ?? process.env.OPENAI_MODEL ?? DEFAULT_MODEL;
141
- const apiKey2 = apiKeyEnv ?? process.env.OPENAI_API_KEY;
142
- try {
143
- return new ChatOpenAI({
144
- model: model2,
145
- temperature: 0,
146
- ...apiKey2 ? { apiKey: apiKey2 } : {}
147
- });
148
- } catch (e) {
149
- throw normalizeAgentLlMError(e, "agent-llm: failed to create default ChatOpenAI");
150
- }
151
- }
152
- const provider = defaultConfig.provider ?? "openai";
153
- const chatModelFactory = getChatModelFactory(provider);
154
- if (chatModelFactory) {
155
- const config = {
156
- ...defaultConfig,
157
- model: modelEnv ?? defaultConfig.model,
158
- temperature: typeof defaultConfig.temperature === "number" ? defaultConfig.temperature : 0
159
- };
160
- try {
161
- return chatModelFactory(config);
162
- } catch (e) {
163
- throw normalizeAgentLlMError(e, `agent-llm: failed to create ChatModel for provider "${provider}"`);
164
- }
165
- }
166
- const model = modelEnv ?? defaultConfig?.model ?? process.env.OPENAI_MODEL ?? DEFAULT_MODEL;
167
- let apiKey = apiKeyEnv ?? defaultConfig?.apiKey ?? process.env.OPENAI_API_KEY;
168
- let baseURL = defaultConfig?.baseURL;
169
- if (baseURL && !baseURL.replace(/\/$/, "").endsWith("/v1")) {
170
- baseURL = baseURL.replace(/\/$/, "") + "/v1";
171
- }
172
- if (baseURL && apiKey === void 0) {
173
- apiKey = "ollama";
144
+ const msg = e instanceof Error ? e.message : String(e);
145
+ throw new Error(`agent-llm: failed to read config file ${filePath}: ${msg}`, { cause: e });
174
146
  }
175
- const temperature = typeof defaultConfig?.temperature === "number" ? defaultConfig.temperature : 0;
176
- const constructorOptions = {
177
- model,
178
- temperature,
179
- ...apiKey ? { apiKey } : {},
180
- ...baseURL ? { configuration: { baseURL } } : {}
181
- };
182
147
  try {
183
- return new ChatOpenAI(constructorOptions);
148
+ const llm = parseLlmYaml(raw, options);
149
+ return llm ?? null;
184
150
  } catch (e) {
185
- throw normalizeAgentLlMError(e, "agent-llm: failed to create ChatOpenAI from config");
151
+ const msg = e instanceof Error ? e.message : String(e);
152
+ throw new Error(`agent-llm: failed to parse config file ${filePath}: ${msg}`, { cause: e });
186
153
  }
187
154
  }
188
155
 
@@ -316,8 +283,86 @@ function registerProvider(name, factory) {
316
283
  PROVIDERS[name.toLowerCase()] = factory;
317
284
  }
318
285
 
319
- // src/loadLLMExtensions.ts
320
- import { readdirSync, readFileSync, existsSync } from "fs";
286
+ // src/registry/chat-model.ts
287
+ var CHAT_MODEL_FACTORIES = /* @__PURE__ */ new Map();
288
+ function registerChatModelProvider(providerName, factory) {
289
+ CHAT_MODEL_FACTORIES.set(providerName.toLowerCase(), factory);
290
+ }
291
+ function getChatModelFactory(providerName) {
292
+ return CHAT_MODEL_FACTORIES.get(providerName.toLowerCase());
293
+ }
294
+
295
+ // src/langchain/adapter.ts
296
+ import { ChatOpenAI } from "@langchain/openai";
297
+ var DEFAULT_MODEL = "gpt-4o-mini";
298
+ function normalizeAgentLlMError(e, context) {
299
+ if (e instanceof Error) return new Error(`${context}: ${e.message}`, { cause: e });
300
+ return new Error(`${context}: ${String(e)}`);
301
+ }
302
+ function createChatModelFromLlmConfig(options) {
303
+ const { llmSection, modelEnv, apiKeyEnv } = options;
304
+ let defaultId;
305
+ let configs;
306
+ try {
307
+ const parsed = parseLlmSection(llmSection ?? null);
308
+ defaultId = parsed.defaultId;
309
+ configs = parsed.configs;
310
+ } catch (e) {
311
+ throw normalizeAgentLlMError(e, "agent-llm: failed to parse llm section");
312
+ }
313
+ const defaultConfig = configs.find((c) => c.id === defaultId) ?? configs[0];
314
+ if (!defaultConfig) {
315
+ const model2 = modelEnv ?? process.env.OPENAI_MODEL ?? DEFAULT_MODEL;
316
+ const apiKey2 = apiKeyEnv ?? process.env.OPENAI_API_KEY;
317
+ try {
318
+ return new ChatOpenAI({
319
+ model: model2,
320
+ temperature: 0,
321
+ ...apiKey2 ? { apiKey: apiKey2 } : {}
322
+ });
323
+ } catch (e) {
324
+ throw normalizeAgentLlMError(e, "agent-llm: failed to create default ChatOpenAI");
325
+ }
326
+ }
327
+ const provider = defaultConfig.provider ?? "openai";
328
+ const chatModelFactory = getChatModelFactory(provider);
329
+ if (chatModelFactory) {
330
+ const config = {
331
+ ...defaultConfig,
332
+ model: modelEnv ?? defaultConfig.model,
333
+ temperature: typeof defaultConfig.temperature === "number" ? defaultConfig.temperature : 0
334
+ };
335
+ try {
336
+ return chatModelFactory(config);
337
+ } catch (e) {
338
+ throw normalizeAgentLlMError(e, `agent-llm: failed to create ChatModel for provider "${provider}"`);
339
+ }
340
+ }
341
+ const model = modelEnv ?? defaultConfig?.model ?? process.env.OPENAI_MODEL ?? DEFAULT_MODEL;
342
+ let apiKey = apiKeyEnv ?? defaultConfig?.apiKey ?? process.env.OPENAI_API_KEY;
343
+ let baseURL = defaultConfig?.baseURL;
344
+ if (baseURL && !baseURL.replace(/\/$/, "").endsWith("/v1")) {
345
+ baseURL = baseURL.replace(/\/$/, "") + "/v1";
346
+ }
347
+ if (baseURL && apiKey === void 0) {
348
+ apiKey = "ollama";
349
+ }
350
+ const temperature = typeof defaultConfig?.temperature === "number" ? defaultConfig.temperature : 0;
351
+ const constructorOptions = {
352
+ model,
353
+ temperature,
354
+ ...apiKey ? { apiKey } : {},
355
+ ...baseURL ? { configuration: { baseURL } } : {}
356
+ };
357
+ try {
358
+ return new ChatOpenAI(constructorOptions);
359
+ } catch (e) {
360
+ throw normalizeAgentLlMError(e, "agent-llm: failed to create ChatOpenAI from config");
361
+ }
362
+ }
363
+
364
+ // src/extensions/loader.ts
365
+ import { readdirSync, readFileSync as readFileSync2, existsSync as existsSync2 } from "fs";
321
366
  import { join } from "path";
322
367
  import { pathToFileURL } from "url";
323
368
  var loadedPackages = /* @__PURE__ */ new Set();
@@ -356,9 +401,9 @@ function resolveLLMExtensionPackages(types) {
356
401
  );
357
402
  }
358
403
  function readPackageProviderName(pkgPath) {
359
- if (!existsSync(pkgPath)) return null;
404
+ if (!existsSync2(pkgPath)) return null;
360
405
  try {
361
- const raw = readFileSync(pkgPath, "utf-8");
406
+ const raw = readFileSync2(pkgPath, "utf-8");
362
407
  const pkg = JSON.parse(raw);
363
408
  const declared = pkg.agentLlmProvider === true || Array.isArray(pkg.keywords) && pkg.keywords.includes("agent-llm-provider");
364
409
  return declared && typeof pkg.name === "string" ? pkg.name : null;
@@ -369,7 +414,7 @@ function readPackageProviderName(pkgPath) {
369
414
  function discoverLLMExtensions(cwd = process.cwd()) {
370
415
  const dir = typeof cwd === "string" && cwd.trim().length > 0 ? cwd : process.cwd();
371
416
  const nodeModules = join(dir, "node_modules");
372
- if (!existsSync(nodeModules)) return [];
417
+ if (!existsSync2(nodeModules)) return [];
373
418
  const names = [];
374
419
  const seen = /* @__PURE__ */ new Set();
375
420
  try {
@@ -401,13 +446,13 @@ function discoverLLMExtensions(cwd = process.cwd()) {
401
446
  }
402
447
  async function loadModuleFromPath(pkgDir) {
403
448
  const pkgJsonPath = join(pkgDir, "package.json");
404
- if (!existsSync(pkgJsonPath)) {
449
+ if (!existsSync2(pkgJsonPath)) {
405
450
  throw new Error(`package.json not found in ${pkgDir}`);
406
451
  }
407
- const pkgJson = JSON.parse(readFileSync(pkgJsonPath, "utf-8"));
452
+ const pkgJson = JSON.parse(readFileSync2(pkgJsonPath, "utf-8"));
408
453
  const main = pkgJson?.main ?? "index.js";
409
454
  const entryPath = join(pkgDir, main);
410
- if (!existsSync(entryPath)) {
455
+ if (!existsSync2(entryPath)) {
411
456
  throw new Error(`Entry ${main} not found in ${pkgDir}`);
412
457
  }
413
458
  const entryUrl = pathToFileURL(entryPath).href;
@@ -424,9 +469,9 @@ async function loadLLMExtensions(extensionPackages, options) {
424
469
  loadedPackages.add(pkg);
425
470
  let loaded = false;
426
471
  const cwdPkgDir = join(cwd, "node_modules", pkg);
427
- const cwdIsProject = existsSync(join(cwd, "package.json")) && (() => {
472
+ const cwdIsProject = existsSync2(join(cwd, "package.json")) && (() => {
428
473
  try {
429
- const name = JSON.parse(readFileSync(join(cwd, "package.json"), "utf-8")).name;
474
+ const name = JSON.parse(readFileSync2(join(cwd, "package.json"), "utf-8")).name;
430
475
  return name === pkg;
431
476
  } catch {
432
477
  return false;
@@ -434,7 +479,7 @@ async function loadLLMExtensions(extensionPackages, options) {
434
479
  })();
435
480
  const dirsToTry = [cwdPkgDir, ...cwdIsProject ? [cwd] : []];
436
481
  for (const pkgDir of dirsToTry) {
437
- if (!existsSync(join(pkgDir, "package.json"))) continue;
482
+ if (!existsSync2(join(pkgDir, "package.json"))) continue;
438
483
  try {
439
484
  const m = await loadModuleFromPath(pkgDir);
440
485
  const ext = getExtensionFromModule(m);
@@ -480,7 +525,7 @@ async function loadDiscoveredExtensions(cwd = process.cwd()) {
480
525
  return names;
481
526
  }
482
527
 
483
- // src/npmProviderProtocol.ts
528
+ // src/extensions/npm-protocol.ts
484
529
  import { execSync } from "child_process";
485
530
  var NPM_PROTOCOL_PREFIX = "npm:";
486
531
  function parseNpmProviderSpec(spec) {
@@ -636,52 +681,7 @@ async function createChatModelFromLlmConfigWithNpm(options) {
636
681
  }
637
682
  }
638
683
 
639
- // src/loadLlmConfig.ts
640
- import { readFileSync as readFileSync2, existsSync as existsSync2 } from "fs";
641
- import { parse as parseYaml } from "yaml";
642
- function substituteEnv(obj) {
643
- if (obj === null || obj === void 0) return obj;
644
- if (typeof obj === "string") {
645
- const m = obj.match(/^\$\{(\w+)\}$/);
646
- return m ? process.env[m[1]] ?? obj : obj;
647
- }
648
- if (Array.isArray(obj)) return obj.map(substituteEnv);
649
- if (typeof obj === "object") {
650
- const out = {};
651
- for (const [k, v] of Object.entries(obj)) out[k] = substituteEnv(v);
652
- return out;
653
- }
654
- return obj;
655
- }
656
- function parseLlmYaml(content, options = {}) {
657
- const { substituteEnv: doSub = true } = options;
658
- const parsed = parseYaml(content);
659
- const llm = parsed?.llm;
660
- if (llm == null) return void 0;
661
- return doSub ? substituteEnv(llm) : llm;
662
- }
663
- function loadLlmConfig(filePath, options = {}) {
664
- if (typeof filePath !== "string" || filePath.trim().length === 0) {
665
- throw new Error("agent-llm: loadLlmConfig requires a non-empty file path");
666
- }
667
- if (!existsSync2(filePath)) return null;
668
- let raw;
669
- try {
670
- raw = readFileSync2(filePath, "utf8");
671
- } catch (e) {
672
- const msg = e instanceof Error ? e.message : String(e);
673
- throw new Error(`agent-llm: failed to read config file ${filePath}: ${msg}`, { cause: e });
674
- }
675
- try {
676
- const llm = parseLlmYaml(raw, options);
677
- return llm ?? null;
678
- } catch (e) {
679
- const msg = e instanceof Error ? e.message : String(e);
680
- throw new Error(`agent-llm: failed to parse config file ${filePath}: ${msg}`, { cause: e });
681
- }
682
- }
683
-
684
- // src/createAgentLlM.ts
684
+ // src/api/create-agent-llm.ts
685
685
  import { join as join2 } from "path";
686
686
  function resolveDefaultConfigPath() {
687
687
  const cwd = process.cwd();
@@ -717,14 +717,17 @@ async function createAgentLlM(configPathOrOptions) {
717
717
 
718
718
  export {
719
719
  parseLlmSection,
720
- registerChatModelProvider,
721
- getChatModelFactory,
722
- createChatModelFromLlmConfig,
720
+ substituteEnv,
721
+ parseLlmYaml,
722
+ loadLlmConfig,
723
723
  createOpenAIChatClient,
724
724
  createOpenAIImageClient,
725
725
  createOpenAIClient,
726
726
  createClient,
727
727
  registerProvider,
728
+ registerChatModelProvider,
729
+ getChatModelFactory,
730
+ createChatModelFromLlmConfig,
728
731
  resolveLLMExtensionPackages,
729
732
  discoverLLMExtensions,
730
733
  loadLLMExtensions,
@@ -736,9 +739,6 @@ export {
736
739
  resolveNpmProvider,
737
740
  resolveLlmSectionWithNpm,
738
741
  createChatModelFromLlmConfigWithNpm,
739
- substituteEnv,
740
- parseLlmYaml,
741
- loadLlmConfig,
742
742
  createAgentLlM
743
743
  };
744
- //# sourceMappingURL=chunk-L3K6IEC6.js.map
744
+ //# sourceMappingURL=chunk-VR7BRFGB.js.map