@easynet/agent-model 1.0.76 → 1.0.78

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,76 +1,34 @@
1
1
  # @easynet/agent-model
2
2
 
3
- 统一的 Model Hub:从 `model.yaml` 创建 LangChain ChatModel、Embedding 等模型。
3
+ ## Introduction
4
4
 
5
- ## 最小接口
5
+ `@easynet/agent-model` initializes the framework model layer from `model.yaml` and registers the configured chat model, embedding model, and optional VLM model into the default `AgentContext`.
6
6
 
7
- ```ts
8
- import { AgentContextTokens, getDefaultAgentContext } from "@easynet/agent-common";
9
- import { createAgentModel } from "@easynet/agent-model";
7
+ ## API Reference
10
8
 
11
- await createAgentModel();
12
- const llm = getDefaultAgentContext().get(AgentContextTokens.ChatModel);
13
- const result = await llm.invoke("hello");
14
- console.log(result.content);
15
- ```
9
+ | API | What it does | Minimal usage |
10
+ | --- | --- | --- |
11
+ | `createAgentModel` | Load model config and register models into `AgentContext`. | `await createAgentModel({ configPath: "./model.yaml" })` |
16
12
 
17
- ## 最小 YAML(推荐先用这个)
13
+ ## Usage
18
14
 
19
- `model.yaml`
15
+ Create `model.yaml`:
20
16
 
21
17
  ```yaml
22
18
  llm:
23
- # 默认使用 small 这个实例
24
19
  default: small
25
-
26
- # 可按需保留 strong;不需要就删掉
27
- strong:
28
- provider: openai
29
- base_url: ${LLM_BASE_URL}
30
- model: ${LLM_MODEL}
31
-
32
- # 本地 Ollama 最常见配置
33
20
  small:
34
21
  provider: openai
35
22
  base_url: http://localhost:11434/v1
36
23
  model: qwen3:0.6b
37
-
38
- embed:
39
- default: gemma
40
- gemma:
41
- provider: openai
42
- base_url: https://ollama-nvidia-8g-2.easynet.world/v1
43
- model: embeddinggemma:latest
44
- apiKey: ollama
45
-
46
- runtime:
47
- check_connectivity: false
48
24
  ```
49
25
 
50
- ## 最简单示例(带注释)
26
+ Initialize the model layer:
51
27
 
52
28
  ```ts
53
- import { AgentContextTokens, getDefaultAgentContext } from "@easynet/agent-common";
54
29
  import { createAgentModel } from "@easynet/agent-model";
55
30
 
56
- async function main() {
57
- // 1) 从当前目录 model.yaml 读取配置并创建模型
58
- await createAgentModel();
59
- const llm = getDefaultAgentContext().get(AgentContextTokens.ChatModel);
60
-
61
- // 2) 直接调用模型
62
- const response = await llm.invoke("请用一句话介绍你自己。");
63
-
64
- // 3) 输出文本
65
- console.log(response.content);
66
- }
67
-
68
- main().catch(console.error);
31
+ await createAgentModel({
32
+ configPath: "./model.yaml",
33
+ });
69
34
  ```
70
-
71
- ## 可选扩展
72
-
73
- - 自定义 provider:`registerChatModelProvider(...)`
74
- - 只取默认模型配置:`getDefaultLlmConfig(...)`
75
- - 直接从对象构建模型:`createChatModelFromLlmConfig(...)`
76
- - 从 model.yaml 创建 EmbedFn:`createEmbedFnFromModelsConfig(...)`
@@ -0,0 +1,3 @@
1
+ import { type AgentContext } from "@easynet/agent-common";
2
+ export declare function getDefaultAgentContext(): AgentContext;
3
+ //# sourceMappingURL=agent-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-context.d.ts","sourceRoot":"","sources":["../src/agent-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAc9E,wBAAgB,sBAAsB,IAAI,YAAY,CAQrD"}
@@ -1 +1 @@
1
- {"version":3,"file":"register-model.d.ts","sourceRoot":"","sources":["../../src/api/register-model.ts"],"names":[],"mappings":"AACA,OAAO,EAA4B,KAAK,+BAA+B,EAAE,MAAM,kCAAkC,CAAC;AAElH,MAAM,WAAW,uBAAwB,SAAQ,+BAA+B;CAAG;AAEnF;;;;;;;;;;;;;GAaG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,CAAC,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBvF"}
1
+ {"version":3,"file":"register-model.d.ts","sourceRoot":"","sources":["../../src/api/register-model.ts"],"names":[],"mappings":"AAEA,OAAO,EAA4B,KAAK,+BAA+B,EAAE,MAAM,kCAAkC,CAAC;AAElH,MAAM,WAAW,uBAAwB,SAAQ,+BAA+B;CAAG;AAEnF;;;;;;;;;;;;;GAaG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,CAAC,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBvF"}
@@ -206,15 +206,132 @@ async function loadDiscoveredExtensions(cwd = process.cwd()) {
206
206
  return names;
207
207
  }
208
208
 
209
+ // src/npm/provider.ts
210
+ var NPM_PROTOCOL_PREFIX = "npm:";
211
+ function isNpmProviderSpec(spec) {
212
+ return typeof spec === "string" && spec.startsWith(NPM_PROTOCOL_PREFIX);
213
+ }
214
+ function parseNpmProvider(provider) {
215
+ if (!isNpmProviderSpec(provider)) return null;
216
+ const rest = provider.slice(NPM_PROTOCOL_PREFIX.length);
217
+ const hashIdx = rest.indexOf("#");
218
+ const fragment = hashIdx >= 0 ? rest.slice(hashIdx + 1) : void 0;
219
+ const beforeHash = hashIdx >= 0 ? rest.slice(0, hashIdx) : rest;
220
+ const atIdx = beforeHash.startsWith("@") ? beforeHash.indexOf("@", 1) : beforeHash.lastIndexOf("@");
221
+ const pkg = atIdx > 0 ? beforeHash.slice(0, atIdx) : beforeHash;
222
+ const tag = atIdx > 0 ? beforeHash.slice(atIdx + 1) : void 0;
223
+ return { pkg: pkg || beforeHash, tag: tag || void 0, fragment };
224
+ }
225
+ function parseNpmProviderSpec(spec) {
226
+ const parsed = parseNpmProvider(spec);
227
+ if (!parsed) return null;
228
+ return {
229
+ packageName: parsed.pkg,
230
+ version: parsed.tag,
231
+ provider: parsed.fragment
232
+ };
233
+ }
234
+
235
+ // src/npm/install.ts
236
+ import { execFileSync as execFileSync2 } from "child_process";
237
+
238
+ // src/npm/version.ts
239
+ import { execFileSync } from "child_process";
240
+ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
241
+ import path from "path";
242
+ var versionCache = /* @__PURE__ */ new Map();
243
+ var CACHE_TTL = 5 * 60 * 1e3;
244
+ function resolveNpmPackageVersion(packageName, tag, options = {}) {
245
+ const cacheKey = tag ? `${packageName}@${tag}` : packageName;
246
+ const cached = versionCache.get(cacheKey);
247
+ if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
248
+ return cached.version;
249
+ }
250
+ try {
251
+ const spec = tag ? `${packageName}@${tag}` : packageName;
252
+ const out = execFileSync("npm", ["view", spec, "version"], {
253
+ cwd: options.cwd ?? process.cwd(),
254
+ encoding: "utf-8",
255
+ timeout: options.timeoutMs ?? 8e3,
256
+ stdio: ["ignore", "pipe", "pipe"]
257
+ });
258
+ const version = out?.trim() ?? null;
259
+ if (version) {
260
+ versionCache.set(cacheKey, { version, timestamp: Date.now() });
261
+ }
262
+ return version;
263
+ } catch {
264
+ return null;
265
+ }
266
+ }
267
+ function resolveLatestVersionFromRegistry(packageName, options = {}) {
268
+ const version = resolveNpmPackageVersion(packageName, void 0, options);
269
+ if (!version) {
270
+ throw new Error(`Failed to resolve latest version for ${packageName}`);
271
+ }
272
+ return version;
273
+ }
274
+ function getInstalledVersion(packageName, options = {}) {
275
+ let dir = path.resolve(options.cwd ?? process.cwd());
276
+ const segments = packageName.split("/");
277
+ while (true) {
278
+ const pkgJsonPath = path.join(dir, "node_modules", ...segments, "package.json");
279
+ if (existsSync2(pkgJsonPath)) {
280
+ try {
281
+ const pkg = JSON.parse(readFileSync2(pkgJsonPath, "utf-8"));
282
+ return typeof pkg.version === "string" ? pkg.version : null;
283
+ } catch {
284
+ return null;
285
+ }
286
+ }
287
+ const parent = path.dirname(dir);
288
+ if (parent === dir) return null;
289
+ dir = parent;
290
+ }
291
+ }
292
+
293
+ // src/npm/install.ts
294
+ var VERSION_LATEST = "latest";
295
+ function resolveInstallVersion(packageName, version, cwd) {
296
+ const isLatestOrEmpty = version === void 0 || version === "" || typeof version === "string" && version.toLowerCase() === VERSION_LATEST;
297
+ if (isLatestOrEmpty) {
298
+ return resolveLatestVersionFromRegistry(packageName, { cwd });
299
+ }
300
+ return version;
301
+ }
302
+ async function ensureNpmPackageInstalled(packageName, options = {}) {
303
+ if (typeof packageName !== "string" || packageName.trim().length === 0) {
304
+ throw new Error("ensureNpmPackageInstalled requires a non-empty package name");
305
+ }
306
+ const cwd = options.cwd ?? process.cwd();
307
+ const resolvedVersion = resolveInstallVersion(packageName, options.version, cwd);
308
+ const installedVersion = getInstalledVersion(packageName, { cwd });
309
+ if (installedVersion === resolvedVersion) return;
310
+ const installSpec = `${packageName}@${resolvedVersion}`;
311
+ const prefix = options.logPrefix ?? "[agent-model]";
312
+ if (installedVersion === null) {
313
+ console.info(`${prefix} Installing provider: ${installSpec}`);
314
+ } else {
315
+ console.info(`${prefix} Updating provider: ${packageName} ${installedVersion} -> ${resolvedVersion}`);
316
+ }
317
+ const args = ["install", installSpec];
318
+ if (options.noPackageLock !== false) args.push("--no-package-lock");
319
+ const stdio = options.stdio === "pipe" ? ["ignore", "pipe", "pipe"] : options.stdio ?? "inherit";
320
+ try {
321
+ execFileSync2("npm", args, {
322
+ cwd,
323
+ stdio,
324
+ encoding: "utf-8"
325
+ });
326
+ } catch (error) {
327
+ const message = error instanceof Error ? error.message : String(error);
328
+ throw new Error(`npm install failed for ${installSpec}: ${message}`, { cause: error });
329
+ }
330
+ }
331
+
209
332
  // src/extensions/npm-protocol.ts
210
- import {
211
- NPM_PROTOCOL_PREFIX,
212
- parseNpmProviderSpec,
213
- isNpmProviderSpec,
214
- ensureNpmPackageInstalled as ensureNpmPackageInstalledFromCommon
215
- } from "@easynet/agent-common/npm";
216
333
  async function ensureNpmProviderInstalled(packageName, options = {}) {
217
- await ensureNpmPackageInstalledFromCommon(packageName, {
334
+ await ensureNpmPackageInstalled(packageName, {
218
335
  version: options.version,
219
336
  cwd: options.cwd,
220
337
  stdio: "inherit",
@@ -338,10 +455,10 @@ export {
338
455
  loadLLMExtensions,
339
456
  loadDiscoveredExtensions,
340
457
  NPM_PROTOCOL_PREFIX,
341
- parseNpmProviderSpec,
342
458
  isNpmProviderSpec,
459
+ parseNpmProviderSpec,
343
460
  resolveNpmProvider,
344
461
  resolveLlmSectionWithNpm,
345
462
  createChatModelWithNpm
346
463
  };
347
- //# sourceMappingURL=chunk-NAH4USJ2.js.map
464
+ //# sourceMappingURL=chunk-FA6A72OA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/extensions/loader.ts","../src/types.ts","../src/npm/provider.ts","../src/npm/install.ts","../src/npm/version.ts","../src/extensions/npm-protocol.ts"],"sourcesContent":["/**\n * Load LLM extensions by npm package name or by dynamic discovery.\n * Extensions register a ChatModel factory via registerChatModelProvider.\n */\n\nimport { readdirSync, readFileSync, existsSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { join } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type { ILLMExtension } from \"../types.js\";\nimport { AGENT_LLM_PROVIDER_FIELD } from \"../types.js\";\nimport { registerChatModelProvider, type ChatModelFactory } from \"../registry/chat-model.js\";\n\nconst loadedPackages = new Set<string>();\n\nfunction isLLMExtension(m: unknown): m is ILLMExtension {\n if (m == null || typeof m !== \"object\") return false;\n const e = m as ILLMExtension;\n if (typeof e.providerName !== \"string\") return false;\n const hasRegister = typeof e.register === \"function\";\n const hasChatModel = typeof e.createChatModel === \"function\";\n return hasRegister || hasChatModel;\n}\n\nfunction registerExtension(ext: ILLMExtension): void {\n if (typeof ext.createChatModel === \"function\") {\n registerChatModelProvider(ext.providerName, ext.createChatModel as ChatModelFactory);\n return;\n }\n if (typeof ext.register === \"function\") {\n ext.register();\n }\n}\n\nfunction getExtensionFromModule(m: Record<string, unknown>): ILLMExtension | null {\n if (isLLMExtension(m)) return m;\n if (typeof m.getLLMExtension === \"function\") {\n const ext = m.getLLMExtension();\n return isLLMExtension(ext) ? ext : null;\n }\n if (isLLMExtension(m.default)) return m.default;\n return null;\n}\n\nexport function resolveLLMExtensionPackages(types?: string | string[]): string[] {\n if (types == null) return [];\n const typeList = Array.isArray(types) ? types : [types];\n return typeList.filter(\n (t): t is string => typeof t === \"string\" && String(t).trim().length > 0\n );\n}\n\nfunction readPackageProviderName(pkgPath: string): string | null {\n if (!existsSync(pkgPath)) return null;\n try {\n const raw = readFileSync(pkgPath, \"utf-8\");\n const pkg = JSON.parse(raw) as { agentLlmProvider?: boolean; keywords?: string[]; name?: string };\n const declared =\n pkg[AGENT_LLM_PROVIDER_FIELD] === true ||\n (Array.isArray(pkg.keywords) && pkg.keywords.includes(\"agent-model-provider\"));\n return declared && typeof pkg.name === \"string\" ? pkg.name : null;\n } catch {\n return null;\n }\n}\n\nexport function discoverLLMExtensions(cwd: string = process.cwd()): string[] {\n const dir = typeof cwd === \"string\" && cwd.trim().length > 0 ? cwd : process.cwd();\n const nodeModules = join(dir, \"node_modules\");\n if (!existsSync(nodeModules)) return [];\n const names: string[] = [];\n const seen = new Set<string>();\n try {\n const entries = readdirSync(nodeModules, { withFileTypes: true });\n for (const e of entries) {\n if (e.name.startsWith(\".\") || e.name === \"node\") continue;\n if (e.name.startsWith(\"@\") && e.isDirectory()) {\n const scopePath = join(nodeModules, e.name);\n const scopeEntries = readdirSync(scopePath, { withFileTypes: true });\n for (const se of scopeEntries) {\n if (!se.isDirectory()) continue;\n const name = readPackageProviderName(join(scopePath, se.name, \"package.json\"));\n if (name && !seen.has(name)) {\n seen.add(name);\n names.push(name);\n }\n }\n continue;\n }\n const name = readPackageProviderName(join(nodeModules, e.name, \"package.json\"));\n if (name && !seen.has(name)) {\n seen.add(name);\n names.push(name);\n }\n }\n } catch {\n // no node_modules or not readable\n }\n return names;\n}\n\nasync function loadModuleFromPath(pkgDir: string): Promise<Record<string, unknown>> {\n const pkgJsonPath = join(pkgDir, \"package.json\");\n if (!existsSync(pkgJsonPath)) {\n throw new Error(`package.json not found in ${pkgDir}`);\n }\n const pkgJson = JSON.parse(readFileSync(pkgJsonPath, \"utf-8\")) as { main?: string };\n const main = pkgJson?.main ?? \"index.js\";\n const entryPath = join(pkgDir, main);\n if (!existsSync(entryPath)) {\n throw new Error(`Entry ${main} not found in ${pkgDir}`);\n }\n const entryUrl = pathToFileURL(entryPath).href;\n return (await import(/* @vite-ignore */ entryUrl)) as Record<string, unknown>;\n}\n\n/**\n * Resolve package main entry from cwd so we load the copy in cwd's node_modules,\n * not a different copy from bare import (e.g. under @wallee/agent).\n */\nfunction resolvePackageEntryFromCwd(pkg: string, cwd: string): string | null {\n const pkgDir = join(cwd, \"node_modules\", pkg);\n const pkgJsonPath = join(pkgDir, \"package.json\");\n if (!existsSync(pkgJsonPath)) return null;\n try {\n const req = createRequire(pkgJsonPath);\n return req.resolve(pkg);\n } catch {\n return null;\n }\n}\n\nexport interface LoadLLMExtensionsOptions {\n cwd?: string;\n}\n\nexport async function loadLLMExtensions(\n extensionPackages?: string[],\n options?: LoadLLMExtensionsOptions\n): Promise<void> {\n const packages = Array.isArray(extensionPackages)\n ? extensionPackages.filter((p): p is string => typeof p === \"string\" && String(p).trim().length > 0)\n : [];\n const cwd = options?.cwd ?? process.cwd();\n for (const pkg of packages) {\n if (loadedPackages.has(pkg)) continue;\n loadedPackages.add(pkg);\n let loaded = false;\n const cwdPkgDir = join(cwd, \"node_modules\", pkg);\n const cwdIsProject =\n existsSync(join(cwd, \"package.json\")) &&\n (() => {\n try {\n const name = (JSON.parse(readFileSync(join(cwd, \"package.json\"), \"utf-8\")) as { name?: string }).name;\n return name === pkg;\n } catch {\n return false;\n }\n })();\n const dirsToTry = [cwdPkgDir, ...(cwdIsProject ? [cwd] : [])];\n for (const pkgDir of dirsToTry) {\n if (!existsSync(join(pkgDir, \"package.json\"))) continue;\n try {\n const m = await loadModuleFromPath(pkgDir);\n const ext = getExtensionFromModule(m);\n if (ext) {\n registerExtension(ext);\n loaded = true;\n break;\n }\n if (typeof (m as { registerLLMExtension?: () => void }).registerLLMExtension === \"function\") {\n (m as { registerLLMExtension: () => void }).registerLLMExtension();\n loaded = true;\n break;\n }\n } catch {\n // try next path\n }\n }\n if (loaded) continue;\n // Prefer cwd-resolved entry so we load the copy just installed, not another copy from bare import\n const resolvedEntry = resolvePackageEntryFromCwd(pkg, cwd);\n if (resolvedEntry) {\n try {\n const entryUrl = pathToFileURL(resolvedEntry).href;\n const m = (await import(/* @vite-ignore */ entryUrl)) as Record<string, unknown>;\n const ext = getExtensionFromModule(m);\n if (ext) {\n registerExtension(ext);\n continue;\n }\n if (typeof (m as { registerLLMExtension?: () => void }).registerLLMExtension === \"function\") {\n (m as { registerLLMExtension: () => void }).registerLLMExtension();\n continue;\n }\n } catch {\n // fall through to bare import\n }\n }\n try {\n const m = await import(/* @vite-ignore */ pkg) as Record<string, unknown>;\n const ext = getExtensionFromModule(m);\n if (ext) {\n registerExtension(ext);\n continue;\n }\n if (typeof (m as { registerLLMExtension?: () => void }).registerLLMExtension === \"function\") {\n (m as { registerLLMExtension: () => void }).registerLLMExtension();\n }\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n if (typeof process !== \"undefined\" && process.emitWarning) {\n process.emitWarning(`[agent-model] Failed to load extension \"${pkg}\": ${msg}`, { code: \"AGENT_LLM_EXTENSION_LOAD\" });\n }\n }\n }\n}\n\nexport async function loadDiscoveredExtensions(cwd: string = process.cwd()): Promise<string[]> {\n const dir = typeof cwd === \"string\" && cwd.trim().length > 0 ? cwd : process.cwd();\n const names = discoverLLMExtensions(dir);\n await loadLLMExtensions(names);\n return names;\n}\n","/**\n * Agent LLM: OpenAI-compatible config.\n * Returns LangChain BaseChatModel instances.\n */\n\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\n\n// LLM types now live locally in agent-model\nexport type { LLMType, LLMConfig, AgentConfigLlmSection } from \"./model/types.js\";\n\n/** package.json field: when true, the package is an agent-model provider (legacy name kept for compatibility). */\nexport const AGENT_LLM_PROVIDER_FIELD = \"agentLlmProvider\";\n\n/**\n * Extension interface: register a ChatModel factory by provider name.\n * Extensions implement getLLMExtension(); framework registers the factory when loading.\n */\nexport interface ILLMExtension {\n readonly providerName: string;\n /** ChatModel factory. Framework calls registerChatModelProvider(providerName, createChatModel). */\n readonly createChatModel?: (config: import(\"./model/types.js\").LLMConfig) => BaseChatModel;\n /** Legacy: if extension provides register(), framework calls it. */\n register?(): void;\n}\n","export const NPM_PROTOCOL_PREFIX = \"npm:\";\n\nexport interface NpmProviderInfo {\n pkg: string;\n tag?: string;\n fragment?: string;\n}\n\nexport interface NpmProviderSpec {\n packageName: string;\n version?: string;\n provider?: string;\n}\n\nexport function isNpmProviderSpec(spec: unknown): spec is string {\n return typeof spec === \"string\" && spec.startsWith(NPM_PROTOCOL_PREFIX);\n}\n\nexport function parseNpmProvider(provider: string): NpmProviderInfo | null {\n if (!isNpmProviderSpec(provider)) return null;\n\n const rest = provider.slice(NPM_PROTOCOL_PREFIX.length);\n const hashIdx = rest.indexOf(\"#\");\n const fragment = hashIdx >= 0 ? rest.slice(hashIdx + 1) : undefined;\n const beforeHash = hashIdx >= 0 ? rest.slice(0, hashIdx) : rest;\n const atIdx = beforeHash.startsWith(\"@\") ? beforeHash.indexOf(\"@\", 1) : beforeHash.lastIndexOf(\"@\");\n const pkg = atIdx > 0 ? beforeHash.slice(0, atIdx) : beforeHash;\n const tag = atIdx > 0 ? beforeHash.slice(atIdx + 1) : undefined;\n\n return { pkg: pkg || beforeHash, tag: tag || undefined, fragment };\n}\n\nexport function parseNpmProviderSpec(spec: string): NpmProviderSpec | null {\n const parsed = parseNpmProvider(spec);\n if (!parsed) return null;\n\n return {\n packageName: parsed.pkg,\n version: parsed.tag,\n provider: parsed.fragment,\n };\n}\n","import { execFileSync, type ExecFileSyncOptions } from \"node:child_process\";\nimport { getInstalledVersion, resolveLatestVersionFromRegistry } from \"./version.js\";\n\nconst VERSION_LATEST = \"latest\";\n\nexport interface EnsureNpmPackageInstalledOptions {\n version?: string;\n cwd?: string;\n stdio?: \"inherit\" | \"pipe\";\n noPackageLock?: boolean;\n logPrefix?: string;\n}\n\nfunction resolveInstallVersion(\n packageName: string,\n version: string | undefined,\n cwd: string,\n): string {\n const isLatestOrEmpty =\n version === undefined ||\n version === \"\" ||\n (typeof version === \"string\" && version.toLowerCase() === VERSION_LATEST);\n if (isLatestOrEmpty) {\n return resolveLatestVersionFromRegistry(packageName, { cwd });\n }\n return version;\n}\n\nexport async function ensureNpmPackageInstalled(\n packageName: string,\n options: EnsureNpmPackageInstalledOptions = {},\n): Promise<void> {\n if (typeof packageName !== \"string\" || packageName.trim().length === 0) {\n throw new Error(\"ensureNpmPackageInstalled requires a non-empty package name\");\n }\n\n const cwd = options.cwd ?? process.cwd();\n const resolvedVersion = resolveInstallVersion(packageName, options.version, cwd);\n const installedVersion = getInstalledVersion(packageName, { cwd });\n if (installedVersion === resolvedVersion) return;\n\n const installSpec = `${packageName}@${resolvedVersion}`;\n const prefix = options.logPrefix ?? \"[agent-model]\";\n if (installedVersion === null) {\n console.info(`${prefix} Installing provider: ${installSpec}`);\n } else {\n console.info(`${prefix} Updating provider: ${packageName} ${installedVersion} -> ${resolvedVersion}`);\n }\n\n const args = [\"install\", installSpec];\n if (options.noPackageLock !== false) args.push(\"--no-package-lock\");\n\n const stdio: ExecFileSyncOptions[\"stdio\"] =\n options.stdio === \"pipe\"\n ? [\"ignore\", \"pipe\", \"pipe\"]\n : options.stdio ?? \"inherit\";\n\n try {\n execFileSync(\"npm\", args, {\n cwd,\n stdio,\n encoding: \"utf-8\",\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n throw new Error(`npm install failed for ${installSpec}: ${message}`, { cause: error });\n }\n}\n","import { execFileSync } from \"node:child_process\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport path from \"node:path\";\n\ninterface VersionCacheEntry {\n version: string;\n timestamp: number;\n}\n\nconst versionCache = new Map<string, VersionCacheEntry>();\nconst CACHE_TTL = 5 * 60 * 1000;\n\nexport interface ResolveNpmVersionOptions {\n cwd?: string;\n timeoutMs?: number;\n}\n\nexport function resolveNpmPackageVersion(\n packageName: string,\n tag?: string,\n options: ResolveNpmVersionOptions = {},\n): string | null {\n const cacheKey = tag ? `${packageName}@${tag}` : packageName;\n const cached = versionCache.get(cacheKey);\n if (cached && Date.now() - cached.timestamp < CACHE_TTL) {\n return cached.version;\n }\n\n try {\n const spec = tag ? `${packageName}@${tag}` : packageName;\n const out = execFileSync(\"npm\", [\"view\", spec, \"version\"], {\n cwd: options.cwd ?? process.cwd(),\n encoding: \"utf-8\",\n timeout: options.timeoutMs ?? 8000,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n const version = out?.trim() ?? null;\n if (version) {\n versionCache.set(cacheKey, { version, timestamp: Date.now() });\n }\n return version;\n } catch {\n return null;\n }\n}\n\nexport function resolveLatestVersionFromRegistry(\n packageName: string,\n options: ResolveNpmVersionOptions = {},\n): string {\n const version = resolveNpmPackageVersion(packageName, undefined, options);\n if (!version) {\n throw new Error(`Failed to resolve latest version for ${packageName}`);\n }\n return version;\n}\n\nexport function getInstalledVersion(packageName: string, options: { cwd?: string } = {}): string | null {\n let dir = path.resolve(options.cwd ?? process.cwd());\n const segments = packageName.split(\"/\");\n\n while (true) {\n const pkgJsonPath = path.join(dir, \"node_modules\", ...segments, \"package.json\");\n if (existsSync(pkgJsonPath)) {\n try {\n const pkg = JSON.parse(readFileSync(pkgJsonPath, \"utf-8\")) as { version?: string };\n return typeof pkg.version === \"string\" ? pkg.version : null;\n } catch {\n return null;\n }\n }\n\n const parent = path.dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n","/**\n * npm: protocol in provider — specify an npm package name (and optional version) in config's provider.\n * When installNpmIfMissing is true, the framework will run npm install <package>[@version] if the package is not found.\n */\n\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport { loadLLMExtensions } from \"./loader.js\";\nimport { getChatModelFactory } from \"../registry/chat-model.js\";\nimport { createChatModelFromLlmConfig } from \"../langchain/index.js\";\nimport type { CreateChatModelOptions } from \"../langchain/index.js\";\nimport {\n NPM_PROTOCOL_PREFIX,\n parseNpmProviderSpec,\n isNpmProviderSpec,\n} from \"../npm/provider.js\";\nimport { ensureNpmPackageInstalled } from \"../npm/install.js\";\n\nexport { NPM_PROTOCOL_PREFIX, parseNpmProviderSpec, isNpmProviderSpec };\n\nexport interface EnsureNpmPackageInstalledOptions {\n version?: string;\n cwd?: string;\n}\n\nasync function ensureNpmProviderInstalled(\n packageName: string,\n options: EnsureNpmPackageInstalledOptions = {}\n): Promise<void> {\n await ensureNpmPackageInstalled(packageName, {\n version: options.version,\n cwd: options.cwd,\n stdio: \"inherit\",\n noPackageLock: true,\n logPrefix: \"[agent-model]\",\n });\n}\n\nfunction isModuleNotFoundError(err: unknown): boolean {\n const msg = err instanceof Error ? err.message : String(err);\n return (\n msg.includes(\"Cannot find module\") ||\n msg.includes(\"Cannot find package\") ||\n msg.includes(\"MODULE_NOT_FOUND\") ||\n msg.includes(\"ERR_MODULE_NOT_FOUND\") ||\n msg.includes(\"Failed to load url\") ||\n msg.includes(\"Does the file exist\")\n );\n}\n\n/**\n * Ensure the npm package is installed at the required version.\n * We only use version numbers for management; \"latest\" is always resolved to the actual\n * version from the registry, then we install that version if missing or different.\n */\nexport interface ResolveNpmProviderOptions {\n installNpmIfMissing?: boolean;\n cwd?: string;\n}\n\nfunction normalizeError(e: unknown, context: string): Error {\n if (e instanceof Error) return new Error(`${context}: ${e.message}`, { cause: e });\n return new Error(`${context}: ${String(e)}`);\n}\n\nexport async function resolveNpmProvider(\n spec: string,\n options: ResolveNpmProviderOptions = {}\n): Promise<string | null> {\n if (typeof spec !== \"string\" || spec.trim().length === 0) return null;\n const parsed = parseNpmProviderSpec(spec);\n if (!parsed) return null;\n const { packageName, version, provider: fragmentProvider } = parsed;\n const installNpmIfMissing = options.installNpmIfMissing !== false;\n const cwd = options.cwd ?? process.cwd();\n\n const load = async (): Promise<void> => {\n await loadLLMExtensions([packageName], { cwd });\n };\n\n if (installNpmIfMissing) {\n await ensureNpmProviderInstalled(packageName, { version, cwd });\n }\n\n try {\n await load();\n } catch (err) {\n if (installNpmIfMissing && isModuleNotFoundError(err)) {\n try {\n await ensureNpmProviderInstalled(packageName, { version, cwd });\n await load();\n } catch (installErr) {\n throw normalizeError(installErr, `Failed to install or load npm provider \"${packageName}\"`);\n }\n } else {\n throw normalizeError(err, `Failed to load npm provider \"${packageName}\"`);\n }\n }\n\n if (fragmentProvider && !getChatModelFactory(fragmentProvider)) {\n if (installNpmIfMissing) {\n await ensureNpmProviderInstalled(packageName, { version, cwd });\n await load();\n }\n if (!getChatModelFactory(fragmentProvider)) {\n throw new Error(`Package \"${packageName}\" was installed but did not register provider \"${fragmentProvider}\". Check that the package exports getLLMExtension() or registerLLMExtension().`);\n }\n }\n\n if (fragmentProvider) return fragmentProvider;\n\n try {\n const m = await import(/* @vite-ignore */ packageName);\n if (typeof (m as { getDefaultProviderName?: () => string }).getDefaultProviderName === \"function\") {\n return (m as { getDefaultProviderName: () => string }).getDefaultProviderName();\n }\n } catch {\n // ignore\n }\n throw new Error(\n `Provider spec ${spec} has no #provider fragment and the package does not export getDefaultProviderName(). Use e.g. npm:${packageName}#<provider-name>.`\n );\n}\n\nexport interface ResolveLlmSectionWithNpmOptions extends ResolveNpmProviderOptions {}\n\nexport async function resolveLlmSectionWithNpm(\n llmSection: unknown,\n options: ResolveLlmSectionWithNpmOptions = {}\n): Promise<unknown> {\n if (llmSection == null) return llmSection;\n if (Array.isArray(llmSection)) {\n const out: unknown[] = [];\n for (let i = 0; i < llmSection.length; i++) {\n try {\n out.push(await resolveLlmSectionWithNpm(llmSection[i], options));\n } catch (e) {\n throw normalizeError(e, `Failed to resolve llm section at index ${i}`);\n }\n }\n return out;\n }\n if (typeof llmSection === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(llmSection)) {\n if (k === \"provider\" && isNpmProviderSpec(v)) {\n try {\n const resolved = await resolveNpmProvider(v as string, options);\n out[k] = resolved ?? v;\n } catch (e) {\n throw normalizeError(e, `Failed to resolve provider \"${String(v)}\"`);\n }\n continue;\n }\n try {\n out[k] = await resolveLlmSectionWithNpm(v, options);\n } catch (e) {\n throw normalizeError(e, `Failed to resolve llm section key \"${k}\"`);\n }\n }\n return out;\n }\n return llmSection;\n}\n\nexport interface CreateChatModelWithNpmOptions\n extends CreateChatModelOptions,\n ResolveNpmProviderOptions {}\n\nexport async function createChatModelWithNpm(\n options: CreateChatModelWithNpmOptions = {}\n): Promise<BaseChatModel> {\n try {\n const { installNpmIfMissing, cwd, ...rest } = options;\n const resolvedSection = await resolveLlmSectionWithNpm(options.llmSection ?? null, {\n installNpmIfMissing,\n cwd,\n });\n return createChatModelFromLlmConfig({\n ...rest,\n llmSection: resolvedSection,\n });\n } catch (e) {\n throw normalizeError(e, \"createChatModelWithNpm failed\");\n }\n}\n"],"mappings":"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","names":["name","execFileSync","existsSync","readFileSync","execFileSync"]}
@@ -130,4 +130,4 @@ export {
130
130
  applyDefaultToolChoice2 as applyDefaultToolChoice,
131
131
  ensureConnectivity
132
132
  };
133
- //# sourceMappingURL=chunk-OQPM73A7.js.map
133
+ //# sourceMappingURL=chunk-RNFYO2UB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/config/yaml-utils.ts","../src/config/loader.ts","../src/api/chat-model.ts","../src/api/connectivity.ts"],"sourcesContent":["export {\n loadYamlFile,\n loadYamlFileSync,\n parseYamlContent,\n clearYamlFileCache,\n} from \"@easynet/agent-common\";\n\nexport type { LoadYamlOptions } from \"@easynet/agent-common\";\n\nexport interface YamlEnvOptions {\n substituteEnv?: boolean;\n missingEnv?: \"keep\" | \"empty\" | \"error\";\n}\n","/**\n * Load and parse LLM config from YAML (e.g. model.yaml).\n * Supports ${VAR} substitution from process.env.\n */\nimport { loadYamlFileSync, parseYamlContent } from \"./yaml-utils.js\";\n\nexport interface LoadLlmConfigOptions {\n substituteEnv?: boolean;\n}\n\nfunction substituteEnvInString(input: string): string {\n return input.replace(/\\$\\{([A-Za-z_][A-Za-z0-9_]*)\\}/g, (_, key: string) => {\n return process.env[key] ?? `\\${${key}}`;\n });\n}\n\nexport function substituteEnv(input: unknown): unknown {\n if (typeof input === \"string\") return substituteEnvInString(input);\n if (Array.isArray(input)) return input.map((item) => substituteEnv(item));\n if (input && typeof input === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(input)) out[k] = substituteEnv(v);\n return out;\n }\n return input;\n}\n\nexport function parseLlmYaml(\n content: string,\n options: LoadLlmConfigOptions = {}\n): unknown {\n const { substituteEnv: doSub = true } = options;\n const parsed = parseYamlContent<{ llm?: unknown; spec?: { llm?: unknown } }>(content, {\n substituteEnv: doSub,\n missingEnv: \"keep\",\n });\n const llm = parsed?.spec?.llm ?? parsed?.llm;\n if (llm == null) return undefined;\n return llm;\n}\n\nexport interface ModelConfigResult {\n llm: unknown;\n vlm: unknown;\n embed: unknown;\n runtime: { check_connectivity?: boolean };\n}\n\n/**\n * Load the full model.yaml config, returning llm, vlm, embed, and runtime sections.\n */\nexport function loadModelConfig(\n filePath: string,\n options: LoadLlmConfigOptions = {},\n): ModelConfigResult | null {\n if (typeof filePath !== \"string\" || filePath.trim().length === 0) {\n throw new Error(\"agent-model: loadModelConfig requires a non-empty file path\");\n }\n try {\n const parsed = loadYamlFileSync<{\n llm?: unknown;\n vlm?: unknown;\n embed?: unknown;\n runtime?: Record<string, unknown>;\n spec?: {\n llm?: unknown;\n vlm?: unknown;\n embed?: unknown;\n runtime?: Record<string, unknown>;\n };\n }>(filePath, {\n substituteEnv: options.substituteEnv !== false,\n missingEnv: \"keep\",\n cache: true,\n });\n if (parsed == null) return null;\n const source = parsed.spec ?? parsed;\n return {\n llm: source.llm ?? null,\n vlm: source.vlm ?? null,\n embed: source.embed ?? null,\n runtime: {\n check_connectivity:\n typeof source.runtime?.check_connectivity === \"boolean\"\n ? source.runtime.check_connectivity\n : undefined,\n },\n };\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n throw new Error(`agent-model: failed to parse config file ${filePath}: ${msg}`, { cause: e });\n }\n}\n\n/**\n * Load only the llm section from a YAML config file.\n * @deprecated Use loadModelConfig() instead.\n */\nexport function loadLlmConfig(\n filePath: string,\n options: LoadLlmConfigOptions = {}\n): unknown | null {\n const result = loadModelConfig(filePath, options);\n return result?.llm ?? null;\n}\n","import type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport * as AgentCommon from \"@easynet/agent-common\";\n\n/**\n * Ensure bindTools always receives tool_choice: \"auto\" when tools are bound.\n * Fixes \"Tool choice is none, but model called a tool\" when using this model\n * with LangChain createAgent (AgentNode leaves tool_choice undefined for non-structured tools).\n * Mutates the model in place so it still passes isBaseChatModel / bindTools checks.\n */\nexport function applyDefaultToolChoice(model: BaseChatModel): void {\n const fromCommon = (AgentCommon as Record<string, unknown>).applyDefaultToolChoice;\n if (typeof fromCommon === \"function\") {\n (fromCommon as (value: unknown) => void)(model);\n return;\n }\n const target = model as {\n bindTools?: (tools: unknown, opts?: Record<string, unknown>) => unknown;\n };\n const original = target.bindTools?.bind(model);\n if (!original) return;\n target.bindTools = function (tools: unknown, opts?: Record<string, unknown>) {\n return original(tools, { ...opts, tool_choice: \"auto\" });\n };\n}\n","import {\n buildUnreachableError,\n checkEndpointConnectivity,\n type ConnectionStatus,\n type EndpointConnectivityOptions,\n} from \"@easynet/agent-common\";\nimport { parseLlmSection } from \"../model/llm-parser.js\";\nimport type { LLMConfig } from \"../model/types.js\";\n\nconst CIS_DEFAULT_RESOLVE_HOST = \"s0010-ml-https.s0010.us-west-2.awswd\";\nconst CIS_DEFAULT_RESOLVE_IP = \"10.210.98.124\";\n\nexport interface EnsureConnectivityOptions {\n checkConnectivity?: boolean;\n onConnectionStatus?: (status: ConnectionStatus) => void;\n connectivityTimeoutMs?: number;\n}\n\nfunction buildEndpointConnectivityOptions(\n config: LLMConfig & { baseURL: string }\n): EndpointConnectivityOptions | undefined {\n const opts = (config.options as Record<string, unknown> | undefined) ?? config;\n const provider = typeof config.provider === \"string\" ? config.provider : \"\";\n const baseURL = config.baseURL;\n const isCis = provider === \"cis\" || provider.includes(\"cis\");\n const useCisDefault =\n isCis &&\n baseURL.includes(CIS_DEFAULT_RESOLVE_HOST) &&\n opts?.resolveHost == null;\n\n const resolveHost =\n opts?.resolveHost != null && typeof (opts.resolveHost as { from?: string; to?: string }).from === \"string\"\n ? (opts.resolveHost as { from: string; to: string })\n : useCisDefault\n ? { from: CIS_DEFAULT_RESOLVE_HOST, to: CIS_DEFAULT_RESOLVE_IP }\n : undefined;\n const host = typeof opts?.host === \"string\" ? opts.host : (resolveHost ? resolveHost.from : undefined);\n if (resolveHost == null && host == null) return undefined;\n\n const verifySSL = opts?.verifySSL === true;\n const bypassAuth = opts?.bypassAuth !== false;\n\n return {\n resolveHost,\n host,\n verifySSL: resolveHost != null ? false : (verifySSL ? true : undefined),\n bypassAuth: bypassAuth ? true : undefined,\n featureKey: typeof opts?.featureKey === \"string\" ? opts.featureKey : undefined,\n };\n}\n\nexport async function ensureConnectivity(\n resolvedLlmSection: unknown,\n options: EnsureConnectivityOptions\n): Promise<void> {\n let configs: Array<LLMConfig & { baseURL: string }>;\n try {\n const parsed = parseLlmSection(resolvedLlmSection ?? null);\n configs = parsed.configs.filter(\n (c: LLMConfig): c is LLMConfig & { baseURL: string } =>\n typeof c.baseURL === \"string\" &&\n c.baseURL.length > 0 &&\n (c.baseURL.startsWith(\"http://\") || c.baseURL.startsWith(\"https://\")) &&\n !c.baseURL.includes(\"${\")\n );\n } catch {\n return;\n }\n\n const shouldCheck = options.checkConnectivity !== false && configs.length > 0;\n if (!shouldCheck) return;\n\n const report = (status: ConnectionStatus) => options.onConnectionStatus?.(status);\n const timeoutMs = options.connectivityTimeoutMs ?? 8000;\n\n for (const config of configs) {\n const { id, baseURL } = config;\n report({\n phase: \"checking\",\n endpointId: id,\n baseURL,\n message: \"Checking connection...\",\n });\n\n const endpointOpts = buildEndpointConnectivityOptions(config);\n const result = await checkEndpointConnectivity(baseURL, {\n timeoutMs,\n ...endpointOpts,\n });\n\n if (result.reachable) {\n report({\n phase: \"reachable\",\n endpointId: id,\n baseURL,\n message: result.message ?? \"Connected\",\n });\n continue;\n }\n\n report({\n phase: \"unreachable\",\n endpointId: id,\n baseURL,\n message: result.message ?? \"Unreachable\",\n });\n throw new Error(buildUnreachableError(id, baseURL, result.message));\n }\n}\n"],"mappings":"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","names":["applyDefaultToolChoice"]}
package/dist/cli/index.js CHANGED
@@ -3,10 +3,10 @@ import {
3
3
  applyDefaultToolChoice,
4
4
  ensureConnectivity,
5
5
  loadModelConfig
6
- } from "../chunk-OQPM73A7.js";
6
+ } from "../chunk-RNFYO2UB.js";
7
7
  import {
8
8
  resolveLlmSectionWithNpm
9
- } from "../chunk-NAH4USJ2.js";
9
+ } from "../chunk-FA6A72OA.js";
10
10
  import {
11
11
  createChatModelFromLlmConfig
12
12
  } from "../chunk-UVIUQUYJ.js";
@@ -1,2 +1,7 @@
1
- export { loadYamlFile, loadYamlFileSync, parseYamlContent, clearYamlFileCache, type LoadYamlOptions, type YamlEnvOptions, } from "@easynet/agent-common";
1
+ export { loadYamlFile, loadYamlFileSync, parseYamlContent, clearYamlFileCache, } from "@easynet/agent-common";
2
+ export type { LoadYamlOptions } from "@easynet/agent-common";
3
+ export interface YamlEnvOptions {
4
+ substituteEnv?: boolean;
5
+ missingEnv?: "keep" | "empty" | "error";
6
+ }
2
7
  //# sourceMappingURL=yaml-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"yaml-utils.d.ts","sourceRoot":"","sources":["../../src/config/yaml-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,cAAc,GACpB,MAAM,uBAAuB,CAAC"}
1
+ {"version":3,"file":"yaml-utils.d.ts","sourceRoot":"","sources":["../../src/config/yaml-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,MAAM,WAAW,cAAc;IAC7B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;CACzC"}
@@ -9,7 +9,7 @@ import {
9
9
  resolveLLMExtensionPackages,
10
10
  resolveLlmSectionWithNpm,
11
11
  resolveNpmProvider
12
- } from "../chunk-NAH4USJ2.js";
12
+ } from "../chunk-FA6A72OA.js";
13
13
  import "../chunk-UVIUQUYJ.js";
14
14
  import "../chunk-SPDXNDDD.js";
15
15
  import "../chunk-G7MKWPEI.js";
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import type { BaseChatModel } from "@langchain/core/language_models/chat_models";
6
6
  import type { CreateChatModelOptions } from "../langchain/index.js";
7
- import { NPM_PROTOCOL_PREFIX, parseNpmProviderSpec, isNpmProviderSpec } from "@easynet/agent-common/npm";
7
+ import { NPM_PROTOCOL_PREFIX, parseNpmProviderSpec, isNpmProviderSpec } from "../npm/provider.js";
8
8
  export { NPM_PROTOCOL_PREFIX, parseNpmProviderSpec, isNpmProviderSpec };
9
9
  export interface EnsureNpmPackageInstalledOptions {
10
10
  version?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"npm-protocol.d.ts","sourceRoot":"","sources":["../../src/extensions/npm-protocol.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAIjF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EAElB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,CAAC;AAExE,MAAM,WAAW,gCAAgC;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA2BD;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACxC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAOD,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAsDxB;AAED,MAAM,WAAW,+BAAgC,SAAQ,yBAAyB;CAAG;AAErF,wBAAsB,wBAAwB,CAC5C,UAAU,EAAE,OAAO,EACnB,OAAO,GAAE,+BAAoC,GAC5C,OAAO,CAAC,OAAO,CAAC,CAkClB;AAED,MAAM,WAAW,6BACf,SAAQ,sBAAsB,EAC5B,yBAAyB;CAAG;AAEhC,wBAAsB,sBAAsB,CAC1C,OAAO,GAAE,6BAAkC,GAC1C,OAAO,CAAC,aAAa,CAAC,CAcxB"}
1
+ {"version":3,"file":"npm-protocol.d.ts","sourceRoot":"","sources":["../../src/extensions/npm-protocol.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AAIjF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACpE,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,CAAC;AAExE,MAAM,WAAW,gCAAgC;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA2BD;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACxC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAOD,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAsDxB;AAED,MAAM,WAAW,+BAAgC,SAAQ,yBAAyB;CAAG;AAErF,wBAAsB,wBAAwB,CAC5C,UAAU,EAAE,OAAO,EACnB,OAAO,GAAE,+BAAoC,GAC5C,OAAO,CAAC,OAAO,CAAC,CAkClB;AAED,MAAM,WAAW,6BACf,SAAQ,sBAAsB,EAC5B,yBAAyB;CAAG;AAEhC,wBAAsB,sBAAsB,CAC1C,OAAO,GAAE,6BAAkC,GAC1C,OAAO,CAAC,aAAa,CAAC,CAcxB"}
package/dist/index.js CHANGED
@@ -2,10 +2,10 @@ import {
2
2
  applyDefaultToolChoice,
3
3
  ensureConnectivity,
4
4
  loadModelConfig
5
- } from "./chunk-OQPM73A7.js";
5
+ } from "./chunk-RNFYO2UB.js";
6
6
  import {
7
7
  resolveLlmSectionWithNpm
8
- } from "./chunk-NAH4USJ2.js";
8
+ } from "./chunk-FA6A72OA.js";
9
9
  import {
10
10
  createChatModelFromLlmConfig
11
11
  } from "./chunk-UVIUQUYJ.js";
@@ -18,7 +18,22 @@ import {
18
18
  import "./chunk-G7MKWPEI.js";
19
19
 
20
20
  // src/api/register-model.ts
21
- import { AgentContextTokens, getDefaultAgentContext } from "@easynet/agent-common";
21
+ import { AgentContextTokens } from "@easynet/agent-common";
22
+
23
+ // src/agent-context.ts
24
+ import { createAgentContext } from "@easynet/agent-common";
25
+ var DEFAULT_CONTEXT_KEY = "__easynet_agent_default_context__";
26
+ function isAgentContext(value) {
27
+ return typeof value === "object" && value !== null && typeof value.get === "function" && typeof value.set === "function" && typeof value.has === "function";
28
+ }
29
+ function getDefaultAgentContext() {
30
+ const store = globalThis;
31
+ const existing = store[DEFAULT_CONTEXT_KEY];
32
+ if (isAgentContext(existing)) return existing;
33
+ const created = createAgentContext();
34
+ store[DEFAULT_CONTEXT_KEY] = created;
35
+ return created;
36
+ }
22
37
 
23
38
  // src/api/create-agent-model-registry.ts
24
39
  import { existsSync } from "fs";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/api/register-model.ts","../src/api/create-agent-model-registry.ts"],"sourcesContent":["import { AgentContextTokens, getDefaultAgentContext } from \"@easynet/agent-common\";\nimport { createAgentModelRegistry, type CreateAgentModelRegistryOptions } from \"./create-agent-model-registry.js\";\n\nexport interface CreateAgentModelOptions extends CreateAgentModelRegistryOptions {}\n\n/**\n * Initialize the chat model (and embedding model) and register them into the\n * process-level singleton AgentContext.\n *\n * Sets:\n * - AgentContextTokens.ChatModel → BaseChatModel\n * - AgentContextTokens.EmbedModel → Embeddings\n * - AgentContextTokens.VlmModel → BaseChatModel (image-capable, optional)\n *\n * @example\n * ```ts\n * await createAgentModel({ configPath: \"config/model.yaml\" });\n * ```\n */\nexport async function createAgentModel(options?: CreateAgentModelOptions): Promise<void> {\n const registry = await createAgentModelRegistry(options);\n const llm = await registry.getChatModel();\n const ctx = getDefaultAgentContext();\n ctx.set(AgentContextTokens.ChatModel, llm);\n try {\n const embed = registry.getEmbeddingModel();\n ctx.set(AgentContextTokens.EmbedModel, embed);\n } catch {\n // No embed section configured — embedding model is optional\n }\n try {\n const vlm = await registry.getVlmChatModel();\n ctx.set(AgentContextTokens.VlmModel, vlm);\n } catch {\n // No vlm/image model configured — VLM is optional\n }\n}\n","import { existsSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport type { Embeddings } from \"@langchain/core/embeddings\";\nimport { OpenAIEmbeddings } from \"@langchain/openai\";\nimport { deepMerge, type ConnectionStatus } from \"@easynet/agent-common\";\nimport { loadModelConfig, type ModelConfigResult } from \"../config/loader.js\";\nimport { createChatModelFromLlmConfig } from \"../langchain/index.js\";\nimport { resolveLlmSectionWithNpm } from \"../extensions/npm-protocol.js\";\nimport { parseLlmSection } from \"../model/llm-parser.js\";\nimport { parseEmbedSection } from \"../model/embed-parser.js\";\nimport type { LLMConfig } from \"../model/types.js\";\nimport { applyDefaultToolChoice } from \"./chat-model.js\";\nimport { ensureConnectivity } from \"./connectivity.js\";\n\nexport interface CreateAgentModelRegistryOptions {\n configPath?: string;\n}\n\nexport interface CreateAgentModelChatOptions {\n installNpmIfMissing?: boolean;\n checkConnectivity?: boolean;\n onConnectionStatus?: (status: ConnectionStatus) => void;\n connectivityTimeoutMs?: number;\n}\n\nexport interface AgentModel {\n getChatModel(idOrOptions?: string | CreateAgentModelChatOptions, maybeOptions?: CreateAgentModelChatOptions): Promise<BaseChatModel>;\n getEmbeddingModel(id?: string): Embeddings;\n getVlmChatModel(idOrOptions?: string | CreateAgentModelChatOptions, maybeOptions?: CreateAgentModelChatOptions): Promise<BaseChatModel>;\n}\n\nfunction resolveEmbeddedConfigPath(): string {\n const moduleDir = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n resolve(moduleDir, \"../config/model.yaml\"),\n resolve(moduleDir, \"../model.yaml\"),\n resolve(moduleDir, \"../../config/model.yaml\"),\n resolve(moduleDir, \"../../model.yaml\"),\n ];\n const found = candidates.find((candidate) => existsSync(candidate));\n if (found) return found;\n throw new Error(`createAgentModelRegistry failed: embedded model.yaml not found. Tried: ${candidates.join(\", \")}`);\n}\n\nfunction normalizeOptions(configPathOrOptions?: string | CreateAgentModelRegistryOptions): CreateAgentModelRegistryOptions {\n if (configPathOrOptions == null) return {};\n if (typeof configPathOrOptions === \"string\") return { configPath: configPathOrOptions };\n return configPathOrOptions;\n}\n\nfunction ensureConfig(path: string): ModelConfigResult {\n const loaded = loadModelConfig(path);\n if (!loaded) {\n throw new Error(`createAgentModelRegistry failed: config file not found: ${path}`);\n }\n return loaded;\n}\n\nasync function resolveDefaultVlmConfig(\n merged: ModelConfigResult,\n options: { installNpmIfMissing?: boolean; modelId?: string } = {},\n): Promise<LLMConfig | null> {\n const sourceSection = merged.vlm ?? merged.llm;\n if (sourceSection == null) return null;\n\n const resolved = await resolveLlmSectionWithNpm(sourceSection, {\n installNpmIfMissing: options.installNpmIfMissing !== false,\n cwd: process.cwd(),\n });\n const { defaultId, configs } = parseLlmSection(resolved);\n const imageConfigs = configs.filter((c: LLMConfig) => c.type === \"image\");\n if (imageConfigs.length === 0) return null;\n const targetId = options.modelId ?? defaultId;\n return imageConfigs.find((c: LLMConfig) => c.id === targetId) ?? imageConfigs[0] ?? null;\n}\n\nfunction resolveEmbedConfig(merged: ModelConfigResult, embedId?: string): LLMConfig | null {\n if (!merged.embed) return null;\n const parsed = parseEmbedSection(merged.embed);\n if (parsed.configs.length === 0) return null;\n const id = embedId ?? parsed.defaultId;\n return parsed.configs.find((c) => c.id === id) ?? parsed.configs[0] ?? null;\n}\n\nfunction createLangChainEmbeddingModelFromConfig(config: LLMConfig): Embeddings {\n const opts = (config.options as Record<string, unknown> | undefined) ?? {};\n const baseURLRaw = typeof config.baseURL === \"string\" ? config.baseURL : undefined;\n const baseURL =\n typeof baseURLRaw === \"string\" && baseURLRaw.length > 0\n ? (baseURLRaw.replace(/\\/$/, \"\").endsWith(\"/v1\") ? baseURLRaw : `${baseURLRaw.replace(/\\/$/, \"\")}/v1`)\n : undefined;\n const apiKey = typeof config.apiKey === \"string\" && config.apiKey.length > 0 ? config.apiKey : \"not-needed\";\n const timeout = typeof opts.timeoutMs === \"number\" ? opts.timeoutMs : undefined;\n const dimensions = typeof opts.dimensions === \"number\" ? opts.dimensions : undefined;\n\n return new OpenAIEmbeddings({\n model: typeof config.model === \"string\" && config.model.length > 0 ? config.model : \"text-embedding-3-small\",\n ...(dimensions != null ? { dimensions } : {}),\n ...(timeout != null ? { timeout } : {}),\n apiKey,\n ...(baseURL ? { configuration: { baseURL } } : {}),\n });\n}\n\nexport async function createAgentModelRegistry(configPathOrOptions?: string | CreateAgentModelRegistryOptions): Promise<AgentModel> {\n const options = normalizeOptions(configPathOrOptions);\n const embeddedConfigPath = resolveEmbeddedConfigPath();\n const base = ensureConfig(embeddedConfigPath);\n const override = options.configPath\n ? ensureConfig(resolve(process.cwd(), options.configPath))\n : undefined;\n const merged = override\n ? deepMerge({} as ModelConfigResult, base, override)\n : base;\n\n const resolveChatArgs = (\n idOrOptions?: string | CreateAgentModelChatOptions,\n maybeOptions?: CreateAgentModelChatOptions,\n ): { id?: string; options: CreateAgentModelChatOptions } => {\n if (typeof idOrOptions === \"string\") return { id: idOrOptions, options: maybeOptions ?? {} };\n return { id: undefined, options: idOrOptions ?? {} };\n };\n\n return {\n async getChatModel(\n idOrOptions?: string | CreateAgentModelChatOptions,\n maybeOptions?: CreateAgentModelChatOptions\n ): Promise<BaseChatModel> {\n const { id, options: chatOptions } = resolveChatArgs(idOrOptions, maybeOptions);\n if (merged.llm == null) {\n throw new Error(\"createAgentModelRegistry failed: no llm section configured\");\n }\n const resolvedSection = await resolveLlmSectionWithNpm(merged.llm, {\n installNpmIfMissing: chatOptions.installNpmIfMissing !== false,\n cwd: process.cwd(),\n });\n const parsed = parseLlmSection(resolvedSection);\n const chosenId = id ?? parsed.defaultId;\n const config = parsed.configs.find((c) => c.id === chosenId) ?? parsed.configs[0];\n if (!config) throw new Error(\"createAgentModelRegistry failed: no chat model configured\");\n const llmSection = { default: config.id, [config.id]: config };\n const checkConnectivity = chatOptions.checkConnectivity ?? merged.runtime.check_connectivity;\n await ensureConnectivity(llmSection, { ...chatOptions, checkConnectivity });\n const model = createChatModelFromLlmConfig({ llmSection });\n applyDefaultToolChoice(model);\n return model;\n },\n getEmbeddingModel(embedId?: string): Embeddings {\n const embedConfig = resolveEmbedConfig(merged, embedId);\n if (!embedConfig) {\n throw new Error(\"createAgentModelRegistry failed: no embed model configured\");\n }\n return createLangChainEmbeddingModelFromConfig(embedConfig);\n },\n async getVlmChatModel(\n idOrOptions?: string | CreateAgentModelChatOptions,\n maybeOptions?: CreateAgentModelChatOptions\n ): Promise<BaseChatModel> {\n const { id, options: chatOptions } = resolveChatArgs(idOrOptions, maybeOptions);\n const vlmConfig = await resolveDefaultVlmConfig(merged, {\n installNpmIfMissing: chatOptions.installNpmIfMissing,\n modelId: id,\n });\n if (!vlmConfig) {\n throw new Error(\"createAgentModelRegistry failed: no vlm/image model configured\");\n }\n const section = {\n default: vlmConfig.id,\n [vlmConfig.id]: vlmConfig,\n };\n const checkConnectivity = chatOptions.checkConnectivity ?? merged.runtime.check_connectivity;\n await ensureConnectivity(section, { ...chatOptions, checkConnectivity });\n const model = createChatModelFromLlmConfig({ llmSection: section });\n applyDefaultToolChoice(model);\n return model;\n },\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/api/register-model.ts","../src/agent-context.ts","../src/api/create-agent-model-registry.ts"],"sourcesContent":["import { AgentContextTokens } from \"@easynet/agent-common\";\nimport { getDefaultAgentContext } from \"../agent-context.js\";\nimport { createAgentModelRegistry, type CreateAgentModelRegistryOptions } from \"./create-agent-model-registry.js\";\n\nexport interface CreateAgentModelOptions extends CreateAgentModelRegistryOptions {}\n\n/**\n * Initialize the chat model (and embedding model) and register them into the\n * process-level singleton AgentContext.\n *\n * Sets:\n * - AgentContextTokens.ChatModel → BaseChatModel\n * - AgentContextTokens.EmbedModel → Embeddings\n * - AgentContextTokens.VlmModel → BaseChatModel (image-capable, optional)\n *\n * @example\n * ```ts\n * await createAgentModel({ configPath: \"config/model.yaml\" });\n * ```\n */\nexport async function createAgentModel(options?: CreateAgentModelOptions): Promise<void> {\n const registry = await createAgentModelRegistry(options);\n const llm = await registry.getChatModel();\n const ctx = getDefaultAgentContext();\n ctx.set(AgentContextTokens.ChatModel, llm);\n try {\n const embed = registry.getEmbeddingModel();\n ctx.set(AgentContextTokens.EmbedModel, embed);\n } catch {\n // No embed section configured — embedding model is optional\n }\n try {\n const vlm = await registry.getVlmChatModel();\n ctx.set(AgentContextTokens.VlmModel, vlm);\n } catch {\n // No vlm/image model configured — VLM is optional\n }\n}\n","import { createAgentContext, type AgentContext } from \"@easynet/agent-common\";\n\nconst DEFAULT_CONTEXT_KEY = \"__easynet_agent_default_context__\";\n\nfunction isAgentContext(value: unknown): value is AgentContext {\n return (\n typeof value === \"object\" &&\n value !== null &&\n typeof (value as AgentContext).get === \"function\" &&\n typeof (value as AgentContext).set === \"function\" &&\n typeof (value as AgentContext).has === \"function\"\n );\n}\n\nexport function getDefaultAgentContext(): AgentContext {\n const store = globalThis as Record<string, unknown>;\n const existing = store[DEFAULT_CONTEXT_KEY];\n if (isAgentContext(existing)) return existing;\n\n const created = createAgentContext();\n store[DEFAULT_CONTEXT_KEY] = created;\n return created;\n}\n","import { existsSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport type { Embeddings } from \"@langchain/core/embeddings\";\nimport { OpenAIEmbeddings } from \"@langchain/openai\";\nimport { deepMerge, type ConnectionStatus } from \"@easynet/agent-common\";\nimport { loadModelConfig, type ModelConfigResult } from \"../config/loader.js\";\nimport { createChatModelFromLlmConfig } from \"../langchain/index.js\";\nimport { resolveLlmSectionWithNpm } from \"../extensions/npm-protocol.js\";\nimport { parseLlmSection } from \"../model/llm-parser.js\";\nimport { parseEmbedSection } from \"../model/embed-parser.js\";\nimport type { LLMConfig } from \"../model/types.js\";\nimport { applyDefaultToolChoice } from \"./chat-model.js\";\nimport { ensureConnectivity } from \"./connectivity.js\";\n\nexport interface CreateAgentModelRegistryOptions {\n configPath?: string;\n}\n\nexport interface CreateAgentModelChatOptions {\n installNpmIfMissing?: boolean;\n checkConnectivity?: boolean;\n onConnectionStatus?: (status: ConnectionStatus) => void;\n connectivityTimeoutMs?: number;\n}\n\nexport interface AgentModel {\n getChatModel(idOrOptions?: string | CreateAgentModelChatOptions, maybeOptions?: CreateAgentModelChatOptions): Promise<BaseChatModel>;\n getEmbeddingModel(id?: string): Embeddings;\n getVlmChatModel(idOrOptions?: string | CreateAgentModelChatOptions, maybeOptions?: CreateAgentModelChatOptions): Promise<BaseChatModel>;\n}\n\nfunction resolveEmbeddedConfigPath(): string {\n const moduleDir = dirname(fileURLToPath(import.meta.url));\n const candidates = [\n resolve(moduleDir, \"../config/model.yaml\"),\n resolve(moduleDir, \"../model.yaml\"),\n resolve(moduleDir, \"../../config/model.yaml\"),\n resolve(moduleDir, \"../../model.yaml\"),\n ];\n const found = candidates.find((candidate) => existsSync(candidate));\n if (found) return found;\n throw new Error(`createAgentModelRegistry failed: embedded model.yaml not found. Tried: ${candidates.join(\", \")}`);\n}\n\nfunction normalizeOptions(configPathOrOptions?: string | CreateAgentModelRegistryOptions): CreateAgentModelRegistryOptions {\n if (configPathOrOptions == null) return {};\n if (typeof configPathOrOptions === \"string\") return { configPath: configPathOrOptions };\n return configPathOrOptions;\n}\n\nfunction ensureConfig(path: string): ModelConfigResult {\n const loaded = loadModelConfig(path);\n if (!loaded) {\n throw new Error(`createAgentModelRegistry failed: config file not found: ${path}`);\n }\n return loaded;\n}\n\nasync function resolveDefaultVlmConfig(\n merged: ModelConfigResult,\n options: { installNpmIfMissing?: boolean; modelId?: string } = {},\n): Promise<LLMConfig | null> {\n const sourceSection = merged.vlm ?? merged.llm;\n if (sourceSection == null) return null;\n\n const resolved = await resolveLlmSectionWithNpm(sourceSection, {\n installNpmIfMissing: options.installNpmIfMissing !== false,\n cwd: process.cwd(),\n });\n const { defaultId, configs } = parseLlmSection(resolved);\n const imageConfigs = configs.filter((c: LLMConfig) => c.type === \"image\");\n if (imageConfigs.length === 0) return null;\n const targetId = options.modelId ?? defaultId;\n return imageConfigs.find((c: LLMConfig) => c.id === targetId) ?? imageConfigs[0] ?? null;\n}\n\nfunction resolveEmbedConfig(merged: ModelConfigResult, embedId?: string): LLMConfig | null {\n if (!merged.embed) return null;\n const parsed = parseEmbedSection(merged.embed);\n if (parsed.configs.length === 0) return null;\n const id = embedId ?? parsed.defaultId;\n return parsed.configs.find((c) => c.id === id) ?? parsed.configs[0] ?? null;\n}\n\nfunction createLangChainEmbeddingModelFromConfig(config: LLMConfig): Embeddings {\n const opts = (config.options as Record<string, unknown> | undefined) ?? {};\n const baseURLRaw = typeof config.baseURL === \"string\" ? config.baseURL : undefined;\n const baseURL =\n typeof baseURLRaw === \"string\" && baseURLRaw.length > 0\n ? (baseURLRaw.replace(/\\/$/, \"\").endsWith(\"/v1\") ? baseURLRaw : `${baseURLRaw.replace(/\\/$/, \"\")}/v1`)\n : undefined;\n const apiKey = typeof config.apiKey === \"string\" && config.apiKey.length > 0 ? config.apiKey : \"not-needed\";\n const timeout = typeof opts.timeoutMs === \"number\" ? opts.timeoutMs : undefined;\n const dimensions = typeof opts.dimensions === \"number\" ? opts.dimensions : undefined;\n\n return new OpenAIEmbeddings({\n model: typeof config.model === \"string\" && config.model.length > 0 ? config.model : \"text-embedding-3-small\",\n ...(dimensions != null ? { dimensions } : {}),\n ...(timeout != null ? { timeout } : {}),\n apiKey,\n ...(baseURL ? { configuration: { baseURL } } : {}),\n });\n}\n\nexport async function createAgentModelRegistry(configPathOrOptions?: string | CreateAgentModelRegistryOptions): Promise<AgentModel> {\n const options = normalizeOptions(configPathOrOptions);\n const embeddedConfigPath = resolveEmbeddedConfigPath();\n const base = ensureConfig(embeddedConfigPath);\n const override = options.configPath\n ? ensureConfig(resolve(process.cwd(), options.configPath))\n : undefined;\n const merged = override\n ? deepMerge({} as ModelConfigResult, base, override)\n : base;\n\n const resolveChatArgs = (\n idOrOptions?: string | CreateAgentModelChatOptions,\n maybeOptions?: CreateAgentModelChatOptions,\n ): { id?: string; options: CreateAgentModelChatOptions } => {\n if (typeof idOrOptions === \"string\") return { id: idOrOptions, options: maybeOptions ?? {} };\n return { id: undefined, options: idOrOptions ?? {} };\n };\n\n return {\n async getChatModel(\n idOrOptions?: string | CreateAgentModelChatOptions,\n maybeOptions?: CreateAgentModelChatOptions\n ): Promise<BaseChatModel> {\n const { id, options: chatOptions } = resolveChatArgs(idOrOptions, maybeOptions);\n if (merged.llm == null) {\n throw new Error(\"createAgentModelRegistry failed: no llm section configured\");\n }\n const resolvedSection = await resolveLlmSectionWithNpm(merged.llm, {\n installNpmIfMissing: chatOptions.installNpmIfMissing !== false,\n cwd: process.cwd(),\n });\n const parsed = parseLlmSection(resolvedSection);\n const chosenId = id ?? parsed.defaultId;\n const config = parsed.configs.find((c) => c.id === chosenId) ?? parsed.configs[0];\n if (!config) throw new Error(\"createAgentModelRegistry failed: no chat model configured\");\n const llmSection = { default: config.id, [config.id]: config };\n const checkConnectivity = chatOptions.checkConnectivity ?? merged.runtime.check_connectivity;\n await ensureConnectivity(llmSection, { ...chatOptions, checkConnectivity });\n const model = createChatModelFromLlmConfig({ llmSection });\n applyDefaultToolChoice(model);\n return model;\n },\n getEmbeddingModel(embedId?: string): Embeddings {\n const embedConfig = resolveEmbedConfig(merged, embedId);\n if (!embedConfig) {\n throw new Error(\"createAgentModelRegistry failed: no embed model configured\");\n }\n return createLangChainEmbeddingModelFromConfig(embedConfig);\n },\n async getVlmChatModel(\n idOrOptions?: string | CreateAgentModelChatOptions,\n maybeOptions?: CreateAgentModelChatOptions\n ): Promise<BaseChatModel> {\n const { id, options: chatOptions } = resolveChatArgs(idOrOptions, maybeOptions);\n const vlmConfig = await resolveDefaultVlmConfig(merged, {\n installNpmIfMissing: chatOptions.installNpmIfMissing,\n modelId: id,\n });\n if (!vlmConfig) {\n throw new Error(\"createAgentModelRegistry failed: no vlm/image model configured\");\n }\n const section = {\n default: vlmConfig.id,\n [vlmConfig.id]: vlmConfig,\n };\n const checkConnectivity = chatOptions.checkConnectivity ?? merged.runtime.check_connectivity;\n await ensureConnectivity(section, { ...chatOptions, checkConnectivity });\n const model = createChatModelFromLlmConfig({ llmSection: section });\n applyDefaultToolChoice(model);\n return model;\n },\n };\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,9 @@
1
+ export interface EnsureNpmPackageInstalledOptions {
2
+ version?: string;
3
+ cwd?: string;
4
+ stdio?: "inherit" | "pipe";
5
+ noPackageLock?: boolean;
6
+ logPrefix?: string;
7
+ }
8
+ export declare function ensureNpmPackageInstalled(packageName: string, options?: EnsureNpmPackageInstalledOptions): Promise<void>;
9
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../src/npm/install.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,gCAAgC;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAiBD,wBAAsB,yBAAyB,CAC7C,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,gCAAqC,GAC7C,OAAO,CAAC,IAAI,CAAC,CAoCf"}
@@ -0,0 +1,15 @@
1
+ export declare const NPM_PROTOCOL_PREFIX = "npm:";
2
+ export interface NpmProviderInfo {
3
+ pkg: string;
4
+ tag?: string;
5
+ fragment?: string;
6
+ }
7
+ export interface NpmProviderSpec {
8
+ packageName: string;
9
+ version?: string;
10
+ provider?: string;
11
+ }
12
+ export declare function isNpmProviderSpec(spec: unknown): spec is string;
13
+ export declare function parseNpmProvider(provider: string): NpmProviderInfo | null;
14
+ export declare function parseNpmProviderSpec(spec: string): NpmProviderSpec | null;
15
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/npm/provider.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,SAAS,CAAC;AAE1C,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,IAAI,MAAM,CAE/D;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAYzE;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CASzE"}
@@ -0,0 +1,10 @@
1
+ export interface ResolveNpmVersionOptions {
2
+ cwd?: string;
3
+ timeoutMs?: number;
4
+ }
5
+ export declare function resolveNpmPackageVersion(packageName: string, tag?: string, options?: ResolveNpmVersionOptions): string | null;
6
+ export declare function resolveLatestVersionFromRegistry(packageName: string, options?: ResolveNpmVersionOptions): string;
7
+ export declare function getInstalledVersion(packageName: string, options?: {
8
+ cwd?: string;
9
+ }): string | null;
10
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/npm/version.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,wBAAwB;IACvC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,EACnB,GAAG,CAAC,EAAE,MAAM,EACZ,OAAO,GAAE,wBAA6B,GACrC,MAAM,GAAG,IAAI,CAuBf;AAED,wBAAgB,gCAAgC,CAC9C,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,wBAA6B,GACrC,MAAM,CAMR;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,GAAG,IAAI,CAmBtG"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@easynet/agent-model",
3
- "version": "1.0.76",
3
+ "version": "1.0.78",
4
4
  "description": "Agent LLM: multi-provider, multi-model, simple chat/image API. Consumes agent.yaml llm section.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/extensions/loader.ts","../src/types.ts","../src/extensions/npm-protocol.ts"],"sourcesContent":["/**\n * Load LLM extensions by npm package name or by dynamic discovery.\n * Extensions register a ChatModel factory via registerChatModelProvider.\n */\n\nimport { readdirSync, readFileSync, existsSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { join } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport type { ILLMExtension } from \"../types.js\";\nimport { AGENT_LLM_PROVIDER_FIELD } from \"../types.js\";\nimport { registerChatModelProvider, type ChatModelFactory } from \"../registry/chat-model.js\";\n\nconst loadedPackages = new Set<string>();\n\nfunction isLLMExtension(m: unknown): m is ILLMExtension {\n if (m == null || typeof m !== \"object\") return false;\n const e = m as ILLMExtension;\n if (typeof e.providerName !== \"string\") return false;\n const hasRegister = typeof e.register === \"function\";\n const hasChatModel = typeof e.createChatModel === \"function\";\n return hasRegister || hasChatModel;\n}\n\nfunction registerExtension(ext: ILLMExtension): void {\n if (typeof ext.createChatModel === \"function\") {\n registerChatModelProvider(ext.providerName, ext.createChatModel as ChatModelFactory);\n return;\n }\n if (typeof ext.register === \"function\") {\n ext.register();\n }\n}\n\nfunction getExtensionFromModule(m: Record<string, unknown>): ILLMExtension | null {\n if (isLLMExtension(m)) return m;\n if (typeof m.getLLMExtension === \"function\") {\n const ext = m.getLLMExtension();\n return isLLMExtension(ext) ? ext : null;\n }\n if (isLLMExtension(m.default)) return m.default;\n return null;\n}\n\nexport function resolveLLMExtensionPackages(types?: string | string[]): string[] {\n if (types == null) return [];\n const typeList = Array.isArray(types) ? types : [types];\n return typeList.filter(\n (t): t is string => typeof t === \"string\" && String(t).trim().length > 0\n );\n}\n\nfunction readPackageProviderName(pkgPath: string): string | null {\n if (!existsSync(pkgPath)) return null;\n try {\n const raw = readFileSync(pkgPath, \"utf-8\");\n const pkg = JSON.parse(raw) as { agentLlmProvider?: boolean; keywords?: string[]; name?: string };\n const declared =\n pkg[AGENT_LLM_PROVIDER_FIELD] === true ||\n (Array.isArray(pkg.keywords) && pkg.keywords.includes(\"agent-model-provider\"));\n return declared && typeof pkg.name === \"string\" ? pkg.name : null;\n } catch {\n return null;\n }\n}\n\nexport function discoverLLMExtensions(cwd: string = process.cwd()): string[] {\n const dir = typeof cwd === \"string\" && cwd.trim().length > 0 ? cwd : process.cwd();\n const nodeModules = join(dir, \"node_modules\");\n if (!existsSync(nodeModules)) return [];\n const names: string[] = [];\n const seen = new Set<string>();\n try {\n const entries = readdirSync(nodeModules, { withFileTypes: true });\n for (const e of entries) {\n if (e.name.startsWith(\".\") || e.name === \"node\") continue;\n if (e.name.startsWith(\"@\") && e.isDirectory()) {\n const scopePath = join(nodeModules, e.name);\n const scopeEntries = readdirSync(scopePath, { withFileTypes: true });\n for (const se of scopeEntries) {\n if (!se.isDirectory()) continue;\n const name = readPackageProviderName(join(scopePath, se.name, \"package.json\"));\n if (name && !seen.has(name)) {\n seen.add(name);\n names.push(name);\n }\n }\n continue;\n }\n const name = readPackageProviderName(join(nodeModules, e.name, \"package.json\"));\n if (name && !seen.has(name)) {\n seen.add(name);\n names.push(name);\n }\n }\n } catch {\n // no node_modules or not readable\n }\n return names;\n}\n\nasync function loadModuleFromPath(pkgDir: string): Promise<Record<string, unknown>> {\n const pkgJsonPath = join(pkgDir, \"package.json\");\n if (!existsSync(pkgJsonPath)) {\n throw new Error(`package.json not found in ${pkgDir}`);\n }\n const pkgJson = JSON.parse(readFileSync(pkgJsonPath, \"utf-8\")) as { main?: string };\n const main = pkgJson?.main ?? \"index.js\";\n const entryPath = join(pkgDir, main);\n if (!existsSync(entryPath)) {\n throw new Error(`Entry ${main} not found in ${pkgDir}`);\n }\n const entryUrl = pathToFileURL(entryPath).href;\n return (await import(/* @vite-ignore */ entryUrl)) as Record<string, unknown>;\n}\n\n/**\n * Resolve package main entry from cwd so we load the copy in cwd's node_modules,\n * not a different copy from bare import (e.g. under @wallee/agent).\n */\nfunction resolvePackageEntryFromCwd(pkg: string, cwd: string): string | null {\n const pkgDir = join(cwd, \"node_modules\", pkg);\n const pkgJsonPath = join(pkgDir, \"package.json\");\n if (!existsSync(pkgJsonPath)) return null;\n try {\n const req = createRequire(pkgJsonPath);\n return req.resolve(pkg);\n } catch {\n return null;\n }\n}\n\nexport interface LoadLLMExtensionsOptions {\n cwd?: string;\n}\n\nexport async function loadLLMExtensions(\n extensionPackages?: string[],\n options?: LoadLLMExtensionsOptions\n): Promise<void> {\n const packages = Array.isArray(extensionPackages)\n ? extensionPackages.filter((p): p is string => typeof p === \"string\" && String(p).trim().length > 0)\n : [];\n const cwd = options?.cwd ?? process.cwd();\n for (const pkg of packages) {\n if (loadedPackages.has(pkg)) continue;\n loadedPackages.add(pkg);\n let loaded = false;\n const cwdPkgDir = join(cwd, \"node_modules\", pkg);\n const cwdIsProject =\n existsSync(join(cwd, \"package.json\")) &&\n (() => {\n try {\n const name = (JSON.parse(readFileSync(join(cwd, \"package.json\"), \"utf-8\")) as { name?: string }).name;\n return name === pkg;\n } catch {\n return false;\n }\n })();\n const dirsToTry = [cwdPkgDir, ...(cwdIsProject ? [cwd] : [])];\n for (const pkgDir of dirsToTry) {\n if (!existsSync(join(pkgDir, \"package.json\"))) continue;\n try {\n const m = await loadModuleFromPath(pkgDir);\n const ext = getExtensionFromModule(m);\n if (ext) {\n registerExtension(ext);\n loaded = true;\n break;\n }\n if (typeof (m as { registerLLMExtension?: () => void }).registerLLMExtension === \"function\") {\n (m as { registerLLMExtension: () => void }).registerLLMExtension();\n loaded = true;\n break;\n }\n } catch {\n // try next path\n }\n }\n if (loaded) continue;\n // Prefer cwd-resolved entry so we load the copy just installed, not another copy from bare import\n const resolvedEntry = resolvePackageEntryFromCwd(pkg, cwd);\n if (resolvedEntry) {\n try {\n const entryUrl = pathToFileURL(resolvedEntry).href;\n const m = (await import(/* @vite-ignore */ entryUrl)) as Record<string, unknown>;\n const ext = getExtensionFromModule(m);\n if (ext) {\n registerExtension(ext);\n continue;\n }\n if (typeof (m as { registerLLMExtension?: () => void }).registerLLMExtension === \"function\") {\n (m as { registerLLMExtension: () => void }).registerLLMExtension();\n continue;\n }\n } catch {\n // fall through to bare import\n }\n }\n try {\n const m = await import(/* @vite-ignore */ pkg) as Record<string, unknown>;\n const ext = getExtensionFromModule(m);\n if (ext) {\n registerExtension(ext);\n continue;\n }\n if (typeof (m as { registerLLMExtension?: () => void }).registerLLMExtension === \"function\") {\n (m as { registerLLMExtension: () => void }).registerLLMExtension();\n }\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n if (typeof process !== \"undefined\" && process.emitWarning) {\n process.emitWarning(`[agent-model] Failed to load extension \"${pkg}\": ${msg}`, { code: \"AGENT_LLM_EXTENSION_LOAD\" });\n }\n }\n }\n}\n\nexport async function loadDiscoveredExtensions(cwd: string = process.cwd()): Promise<string[]> {\n const dir = typeof cwd === \"string\" && cwd.trim().length > 0 ? cwd : process.cwd();\n const names = discoverLLMExtensions(dir);\n await loadLLMExtensions(names);\n return names;\n}\n","/**\n * Agent LLM: OpenAI-compatible config.\n * Returns LangChain BaseChatModel instances.\n */\n\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\n\n// LLM types now live locally in agent-model\nexport type { LLMType, LLMConfig, AgentConfigLlmSection } from \"./model/types.js\";\n\n/** package.json field: when true, the package is an agent-model provider (legacy name kept for compatibility). */\nexport const AGENT_LLM_PROVIDER_FIELD = \"agentLlmProvider\";\n\n/**\n * Extension interface: register a ChatModel factory by provider name.\n * Extensions implement getLLMExtension(); framework registers the factory when loading.\n */\nexport interface ILLMExtension {\n readonly providerName: string;\n /** ChatModel factory. Framework calls registerChatModelProvider(providerName, createChatModel). */\n readonly createChatModel?: (config: import(\"./model/types.js\").LLMConfig) => BaseChatModel;\n /** Legacy: if extension provides register(), framework calls it. */\n register?(): void;\n}\n","/**\n * npm: protocol in provider — specify an npm package name (and optional version) in config's provider.\n * When installNpmIfMissing is true, the framework will run npm install <package>[@version] if the package is not found.\n */\n\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport { loadLLMExtensions } from \"./loader.js\";\nimport { getChatModelFactory } from \"../registry/chat-model.js\";\nimport { createChatModelFromLlmConfig } from \"../langchain/index.js\";\nimport type { CreateChatModelOptions } from \"../langchain/index.js\";\nimport {\n NPM_PROTOCOL_PREFIX,\n parseNpmProviderSpec,\n isNpmProviderSpec,\n ensureNpmPackageInstalled as ensureNpmPackageInstalledFromCommon,\n} from \"@easynet/agent-common/npm\";\n\nexport { NPM_PROTOCOL_PREFIX, parseNpmProviderSpec, isNpmProviderSpec };\n\nexport interface EnsureNpmPackageInstalledOptions {\n version?: string;\n cwd?: string;\n}\n\nasync function ensureNpmProviderInstalled(\n packageName: string,\n options: EnsureNpmPackageInstalledOptions = {}\n): Promise<void> {\n await ensureNpmPackageInstalledFromCommon(packageName, {\n version: options.version,\n cwd: options.cwd,\n stdio: \"inherit\",\n noPackageLock: true,\n logPrefix: \"[agent-model]\",\n });\n}\n\nfunction isModuleNotFoundError(err: unknown): boolean {\n const msg = err instanceof Error ? err.message : String(err);\n return (\n msg.includes(\"Cannot find module\") ||\n msg.includes(\"Cannot find package\") ||\n msg.includes(\"MODULE_NOT_FOUND\") ||\n msg.includes(\"ERR_MODULE_NOT_FOUND\") ||\n msg.includes(\"Failed to load url\") ||\n msg.includes(\"Does the file exist\")\n );\n}\n\n/**\n * Ensure the npm package is installed at the required version.\n * We only use version numbers for management; \"latest\" is always resolved to the actual\n * version from the registry, then we install that version if missing or different.\n */\nexport interface ResolveNpmProviderOptions {\n installNpmIfMissing?: boolean;\n cwd?: string;\n}\n\nfunction normalizeError(e: unknown, context: string): Error {\n if (e instanceof Error) return new Error(`${context}: ${e.message}`, { cause: e });\n return new Error(`${context}: ${String(e)}`);\n}\n\nexport async function resolveNpmProvider(\n spec: string,\n options: ResolveNpmProviderOptions = {}\n): Promise<string | null> {\n if (typeof spec !== \"string\" || spec.trim().length === 0) return null;\n const parsed = parseNpmProviderSpec(spec);\n if (!parsed) return null;\n const { packageName, version, provider: fragmentProvider } = parsed;\n const installNpmIfMissing = options.installNpmIfMissing !== false;\n const cwd = options.cwd ?? process.cwd();\n\n const load = async (): Promise<void> => {\n await loadLLMExtensions([packageName], { cwd });\n };\n\n if (installNpmIfMissing) {\n await ensureNpmProviderInstalled(packageName, { version, cwd });\n }\n\n try {\n await load();\n } catch (err) {\n if (installNpmIfMissing && isModuleNotFoundError(err)) {\n try {\n await ensureNpmProviderInstalled(packageName, { version, cwd });\n await load();\n } catch (installErr) {\n throw normalizeError(installErr, `Failed to install or load npm provider \"${packageName}\"`);\n }\n } else {\n throw normalizeError(err, `Failed to load npm provider \"${packageName}\"`);\n }\n }\n\n if (fragmentProvider && !getChatModelFactory(fragmentProvider)) {\n if (installNpmIfMissing) {\n await ensureNpmProviderInstalled(packageName, { version, cwd });\n await load();\n }\n if (!getChatModelFactory(fragmentProvider)) {\n throw new Error(`Package \"${packageName}\" was installed but did not register provider \"${fragmentProvider}\". Check that the package exports getLLMExtension() or registerLLMExtension().`);\n }\n }\n\n if (fragmentProvider) return fragmentProvider;\n\n try {\n const m = await import(/* @vite-ignore */ packageName);\n if (typeof (m as { getDefaultProviderName?: () => string }).getDefaultProviderName === \"function\") {\n return (m as { getDefaultProviderName: () => string }).getDefaultProviderName();\n }\n } catch {\n // ignore\n }\n throw new Error(\n `Provider spec ${spec} has no #provider fragment and the package does not export getDefaultProviderName(). Use e.g. npm:${packageName}#<provider-name>.`\n );\n}\n\nexport interface ResolveLlmSectionWithNpmOptions extends ResolveNpmProviderOptions {}\n\nexport async function resolveLlmSectionWithNpm(\n llmSection: unknown,\n options: ResolveLlmSectionWithNpmOptions = {}\n): Promise<unknown> {\n if (llmSection == null) return llmSection;\n if (Array.isArray(llmSection)) {\n const out: unknown[] = [];\n for (let i = 0; i < llmSection.length; i++) {\n try {\n out.push(await resolveLlmSectionWithNpm(llmSection[i], options));\n } catch (e) {\n throw normalizeError(e, `Failed to resolve llm section at index ${i}`);\n }\n }\n return out;\n }\n if (typeof llmSection === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(llmSection)) {\n if (k === \"provider\" && isNpmProviderSpec(v)) {\n try {\n const resolved = await resolveNpmProvider(v as string, options);\n out[k] = resolved ?? v;\n } catch (e) {\n throw normalizeError(e, `Failed to resolve provider \"${String(v)}\"`);\n }\n continue;\n }\n try {\n out[k] = await resolveLlmSectionWithNpm(v, options);\n } catch (e) {\n throw normalizeError(e, `Failed to resolve llm section key \"${k}\"`);\n }\n }\n return out;\n }\n return llmSection;\n}\n\nexport interface CreateChatModelWithNpmOptions\n extends CreateChatModelOptions,\n ResolveNpmProviderOptions {}\n\nexport async function createChatModelWithNpm(\n options: CreateChatModelWithNpmOptions = {}\n): Promise<BaseChatModel> {\n try {\n const { installNpmIfMissing, cwd, ...rest } = options;\n const resolvedSection = await resolveLlmSectionWithNpm(options.llmSection ?? null, {\n installNpmIfMissing,\n cwd,\n });\n return createChatModelFromLlmConfig({\n ...rest,\n llmSection: resolvedSection,\n });\n } catch (e) {\n throw normalizeError(e, \"createChatModelWithNpm failed\");\n }\n}\n"],"mappings":"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","names":["name"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/config/yaml-utils.ts","../src/config/loader.ts","../src/api/chat-model.ts","../src/api/connectivity.ts"],"sourcesContent":["export {\n loadYamlFile,\n loadYamlFileSync,\n parseYamlContent,\n clearYamlFileCache,\n type LoadYamlOptions,\n type YamlEnvOptions,\n} from \"@easynet/agent-common\";\n","/**\n * Load and parse LLM config from YAML (e.g. model.yaml).\n * Supports ${VAR} substitution from process.env.\n */\nimport { loadYamlFileSync, parseYamlContent } from \"./yaml-utils.js\";\n\nexport interface LoadLlmConfigOptions {\n substituteEnv?: boolean;\n}\n\nfunction substituteEnvInString(input: string): string {\n return input.replace(/\\$\\{([A-Za-z_][A-Za-z0-9_]*)\\}/g, (_, key: string) => {\n return process.env[key] ?? `\\${${key}}`;\n });\n}\n\nexport function substituteEnv(input: unknown): unknown {\n if (typeof input === \"string\") return substituteEnvInString(input);\n if (Array.isArray(input)) return input.map((item) => substituteEnv(item));\n if (input && typeof input === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(input)) out[k] = substituteEnv(v);\n return out;\n }\n return input;\n}\n\nexport function parseLlmYaml(\n content: string,\n options: LoadLlmConfigOptions = {}\n): unknown {\n const { substituteEnv: doSub = true } = options;\n const parsed = parseYamlContent<{ llm?: unknown; spec?: { llm?: unknown } }>(content, {\n substituteEnv: doSub,\n missingEnv: \"keep\",\n });\n const llm = parsed?.spec?.llm ?? parsed?.llm;\n if (llm == null) return undefined;\n return llm;\n}\n\nexport interface ModelConfigResult {\n llm: unknown;\n vlm: unknown;\n embed: unknown;\n runtime: { check_connectivity?: boolean };\n}\n\n/**\n * Load the full model.yaml config, returning llm, vlm, embed, and runtime sections.\n */\nexport function loadModelConfig(\n filePath: string,\n options: LoadLlmConfigOptions = {},\n): ModelConfigResult | null {\n if (typeof filePath !== \"string\" || filePath.trim().length === 0) {\n throw new Error(\"agent-model: loadModelConfig requires a non-empty file path\");\n }\n try {\n const parsed = loadYamlFileSync<{\n llm?: unknown;\n vlm?: unknown;\n embed?: unknown;\n runtime?: Record<string, unknown>;\n spec?: {\n llm?: unknown;\n vlm?: unknown;\n embed?: unknown;\n runtime?: Record<string, unknown>;\n };\n }>(filePath, {\n substituteEnv: options.substituteEnv !== false,\n missingEnv: \"keep\",\n cache: true,\n });\n if (parsed == null) return null;\n const source = parsed.spec ?? parsed;\n return {\n llm: source.llm ?? null,\n vlm: source.vlm ?? null,\n embed: source.embed ?? null,\n runtime: {\n check_connectivity:\n typeof source.runtime?.check_connectivity === \"boolean\"\n ? source.runtime.check_connectivity\n : undefined,\n },\n };\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n throw new Error(`agent-model: failed to parse config file ${filePath}: ${msg}`, { cause: e });\n }\n}\n\n/**\n * Load only the llm section from a YAML config file.\n * @deprecated Use loadModelConfig() instead.\n */\nexport function loadLlmConfig(\n filePath: string,\n options: LoadLlmConfigOptions = {}\n): unknown | null {\n const result = loadModelConfig(filePath, options);\n return result?.llm ?? null;\n}\n","import type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport * as AgentCommon from \"@easynet/agent-common\";\n\n/**\n * Ensure bindTools always receives tool_choice: \"auto\" when tools are bound.\n * Fixes \"Tool choice is none, but model called a tool\" when using this model\n * with LangChain createAgent (AgentNode leaves tool_choice undefined for non-structured tools).\n * Mutates the model in place so it still passes isBaseChatModel / bindTools checks.\n */\nexport function applyDefaultToolChoice(model: BaseChatModel): void {\n const fromCommon = (AgentCommon as Record<string, unknown>).applyDefaultToolChoice;\n if (typeof fromCommon === \"function\") {\n (fromCommon as (value: unknown) => void)(model);\n return;\n }\n const target = model as {\n bindTools?: (tools: unknown, opts?: Record<string, unknown>) => unknown;\n };\n const original = target.bindTools?.bind(model);\n if (!original) return;\n target.bindTools = function (tools: unknown, opts?: Record<string, unknown>) {\n return original(tools, { ...opts, tool_choice: \"auto\" });\n };\n}\n","import {\n buildUnreachableError,\n checkEndpointConnectivity,\n type ConnectionStatus,\n type EndpointConnectivityOptions,\n} from \"@easynet/agent-common\";\nimport { parseLlmSection } from \"../model/llm-parser.js\";\nimport type { LLMConfig } from \"../model/types.js\";\n\nconst CIS_DEFAULT_RESOLVE_HOST = \"s0010-ml-https.s0010.us-west-2.awswd\";\nconst CIS_DEFAULT_RESOLVE_IP = \"10.210.98.124\";\n\nexport interface EnsureConnectivityOptions {\n checkConnectivity?: boolean;\n onConnectionStatus?: (status: ConnectionStatus) => void;\n connectivityTimeoutMs?: number;\n}\n\nfunction buildEndpointConnectivityOptions(\n config: LLMConfig & { baseURL: string }\n): EndpointConnectivityOptions | undefined {\n const opts = (config.options as Record<string, unknown> | undefined) ?? config;\n const provider = typeof config.provider === \"string\" ? config.provider : \"\";\n const baseURL = config.baseURL;\n const isCis = provider === \"cis\" || provider.includes(\"cis\");\n const useCisDefault =\n isCis &&\n baseURL.includes(CIS_DEFAULT_RESOLVE_HOST) &&\n opts?.resolveHost == null;\n\n const resolveHost =\n opts?.resolveHost != null && typeof (opts.resolveHost as { from?: string; to?: string }).from === \"string\"\n ? (opts.resolveHost as { from: string; to: string })\n : useCisDefault\n ? { from: CIS_DEFAULT_RESOLVE_HOST, to: CIS_DEFAULT_RESOLVE_IP }\n : undefined;\n const host = typeof opts?.host === \"string\" ? opts.host : (resolveHost ? resolveHost.from : undefined);\n if (resolveHost == null && host == null) return undefined;\n\n const verifySSL = opts?.verifySSL === true;\n const bypassAuth = opts?.bypassAuth !== false;\n\n return {\n resolveHost,\n host,\n verifySSL: resolveHost != null ? false : (verifySSL ? true : undefined),\n bypassAuth: bypassAuth ? true : undefined,\n featureKey: typeof opts?.featureKey === \"string\" ? opts.featureKey : undefined,\n };\n}\n\nexport async function ensureConnectivity(\n resolvedLlmSection: unknown,\n options: EnsureConnectivityOptions\n): Promise<void> {\n let configs: Array<LLMConfig & { baseURL: string }>;\n try {\n const parsed = parseLlmSection(resolvedLlmSection ?? null);\n configs = parsed.configs.filter(\n (c: LLMConfig): c is LLMConfig & { baseURL: string } =>\n typeof c.baseURL === \"string\" &&\n c.baseURL.length > 0 &&\n (c.baseURL.startsWith(\"http://\") || c.baseURL.startsWith(\"https://\")) &&\n !c.baseURL.includes(\"${\")\n );\n } catch {\n return;\n }\n\n const shouldCheck = options.checkConnectivity !== false && configs.length > 0;\n if (!shouldCheck) return;\n\n const report = (status: ConnectionStatus) => options.onConnectionStatus?.(status);\n const timeoutMs = options.connectivityTimeoutMs ?? 8000;\n\n for (const config of configs) {\n const { id, baseURL } = config;\n report({\n phase: \"checking\",\n endpointId: id,\n baseURL,\n message: \"Checking connection...\",\n });\n\n const endpointOpts = buildEndpointConnectivityOptions(config);\n const result = await checkEndpointConnectivity(baseURL, {\n timeoutMs,\n ...endpointOpts,\n });\n\n if (result.reachable) {\n report({\n phase: \"reachable\",\n endpointId: id,\n baseURL,\n message: result.message ?? \"Connected\",\n });\n continue;\n }\n\n report({\n phase: \"unreachable\",\n endpointId: id,\n baseURL,\n message: result.message ?? \"Unreachable\",\n });\n throw new Error(buildUnreachableError(id, baseURL, result.message));\n }\n}\n"],"mappings":"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","names":["applyDefaultToolChoice"]}