@easynet/agent-model 1.0.89 → 1.0.90
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 +4 -4
- package/config/llm.yaml.example +1 -1
- package/dist/agent-context.d.ts +1 -1
- package/dist/agent-context.d.ts.map +1 -1
- package/dist/api/connectivity.d.ts +1 -1
- package/dist/api/connectivity.d.ts.map +1 -1
- package/dist/api/create-agent-llm.d.ts +1 -1
- package/dist/api/create-agent-llm.d.ts.map +1 -1
- package/dist/api/create-agent-model-registry.d.ts +1 -1
- package/dist/api/create-agent-model-registry.d.ts.map +1 -1
- package/dist/{chunk-D757ZVIH.js → chunk-ZFGQMWFQ.js} +4 -4
- package/dist/chunk-ZFGQMWFQ.js.map +1 -0
- package/dist/cli/index.js +1 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/config/yaml-utils.d.ts +2 -2
- package/dist/config/yaml-utils.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/package.json +7 -3
- package/dist/chunk-D757ZVIH.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
# @
|
|
1
|
+
# @botbotgo/model
|
|
2
2
|
|
|
3
3
|
## Introduction
|
|
4
4
|
|
|
5
|
-
`@
|
|
5
|
+
`@botbotgo/model` loads model configuration and registers the chat model, embedding model, and optional vision model into the default `AgentContext`.
|
|
6
6
|
|
|
7
7
|
## Exposed Interfaces
|
|
8
8
|
|
|
@@ -45,11 +45,11 @@ Key fields:
|
|
|
45
45
|
## Usage
|
|
46
46
|
|
|
47
47
|
```bash
|
|
48
|
-
npm i @
|
|
48
|
+
npm i @botbotgo/model
|
|
49
49
|
```
|
|
50
50
|
|
|
51
51
|
```ts
|
|
52
|
-
import { createAgentModel } from "@
|
|
52
|
+
import { createAgentModel } from "@botbotgo/model";
|
|
53
53
|
|
|
54
54
|
await createAgentModel("./config/model.yaml");
|
|
55
55
|
```
|
package/config/llm.yaml.example
CHANGED
package/dist/agent-context.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-context.d.ts","sourceRoot":"","sources":["../src/agent-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM
|
|
1
|
+
{"version":3,"file":"agent-context.d.ts","sourceRoot":"","sources":["../src/agent-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAcjF,wBAAgB,sBAAsB,IAAI,YAAY,CAQrD"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ConnectionStatus } from "@
|
|
1
|
+
import { type ConnectionStatus } from "@botbotgo/common/connectivity";
|
|
2
2
|
export interface EnsureConnectivityOptions {
|
|
3
3
|
checkConnectivity?: boolean;
|
|
4
4
|
onConnectionStatus?: (status: ConnectionStatus) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connectivity.d.ts","sourceRoot":"","sources":["../../src/api/connectivity.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,gBAAgB,EAEtB,MAAM,
|
|
1
|
+
{"version":3,"file":"connectivity.d.ts","sourceRoot":"","sources":["../../src/api/connectivity.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,gBAAgB,EAEtB,MAAM,+BAA+B,CAAC;AAIvC,MAAM,WAAW,yBAAyB;IACxC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACxD,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAyBD,wBAAsB,kBAAkB,CACtC,kBAAkB,EAAE,OAAO,EAC3B,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,IAAI,CAAC,CAsDf"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { BaseChatModel } from "@langchain/core/language_models/chat_models";
|
|
2
|
-
import type { ConnectionStatus } from "@
|
|
2
|
+
import type { ConnectionStatus } from "@botbotgo/common/connectivity";
|
|
3
3
|
export interface CreateAgentLlmOptions {
|
|
4
4
|
configPath?: string;
|
|
5
5
|
installNpmIfMissing?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-agent-llm.d.ts","sourceRoot":"","sources":["../../src/api/create-agent-llm.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AACjF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"create-agent-llm.d.ts","sourceRoot":"","sources":["../../src/api/create-agent-llm.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AACjF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAOtE,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACxD,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAmBD;;;GAGG;AACH,wBAAsB,cAAc,CAClC,mBAAmB,CAAC,EAAE,MAAM,GAAG,qBAAqB,GACnD,OAAO,CAAC,aAAa,CAAC,CAmCxB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { BaseChatModel } from "@langchain/core/language_models/chat_models";
|
|
2
2
|
import type { Embeddings } from "@langchain/core/embeddings";
|
|
3
|
-
import type { ConnectionStatus } from "@
|
|
3
|
+
import type { ConnectionStatus } from "@botbotgo/common/connectivity";
|
|
4
4
|
export interface CreateAgentModelRegistryOptions {
|
|
5
5
|
configPath?: string;
|
|
6
6
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-agent-model-registry.d.ts","sourceRoot":"","sources":["../../src/api/create-agent-model-registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AACjF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAG7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"create-agent-model-registry.d.ts","sourceRoot":"","sources":["../../src/api/create-agent-model-registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6CAA6C,CAAC;AACjF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAG7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAUtE,MAAM,WAAW,+BAA+B;IAC9C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,2BAA2B;IAC1C,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,kBAAkB,CAAC,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACxD,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,UAAU;IACzB,YAAY,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,2BAA2B,EAAE,YAAY,CAAC,EAAE,2BAA2B,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IACrI,iBAAiB,CAAC,EAAE,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IAC3C,eAAe,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,2BAA2B,EAAE,YAAY,CAAC,EAAE,2BAA2B,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;CACzI;AA2ED,wBAAsB,wBAAwB,CAAC,mBAAmB,CAAC,EAAE,MAAM,GAAG,+BAA+B,GAAG,OAAO,CAAC,UAAU,CAAC,CAyElI"}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
loadYamlFileSync,
|
|
9
9
|
parseYamlContent,
|
|
10
10
|
clearYamlFileCache
|
|
11
|
-
} from "@
|
|
11
|
+
} from "@botbotgo/common/config";
|
|
12
12
|
|
|
13
13
|
// src/config/loader.ts
|
|
14
14
|
function loadModelConfig(filePath, options = {}) {
|
|
@@ -38,7 +38,7 @@ function loadModelConfig(filePath, options = {}) {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
// src/api/chat-model.ts
|
|
41
|
-
import { applyDefaultToolChoice as applyDefaultToolChoiceFromCommon } from "@
|
|
41
|
+
import { applyDefaultToolChoice as applyDefaultToolChoiceFromCommon } from "@botbotgo/common/utils";
|
|
42
42
|
function applyDefaultToolChoice(model) {
|
|
43
43
|
applyDefaultToolChoiceFromCommon(model);
|
|
44
44
|
const target = model;
|
|
@@ -53,7 +53,7 @@ function applyDefaultToolChoice(model) {
|
|
|
53
53
|
import {
|
|
54
54
|
buildUnreachableError,
|
|
55
55
|
checkEndpointConnectivity
|
|
56
|
-
} from "@
|
|
56
|
+
} from "@botbotgo/common/connectivity";
|
|
57
57
|
function buildEndpointConnectivityOptions(config) {
|
|
58
58
|
const opts = config.options ?? config;
|
|
59
59
|
const resolveHost = opts?.resolveHost != null && typeof opts.resolveHost.from === "string" ? opts.resolveHost : void 0;
|
|
@@ -120,4 +120,4 @@ export {
|
|
|
120
120
|
applyDefaultToolChoice,
|
|
121
121
|
ensureConnectivity
|
|
122
122
|
};
|
|
123
|
-
//# sourceMappingURL=chunk-
|
|
123
|
+
//# sourceMappingURL=chunk-ZFGQMWFQ.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 \"@botbotgo/common/config\";\n\nexport type { LoadYamlOptions } from \"@botbotgo/common/config\";\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 { applyDefaultToolChoice as applyDefaultToolChoiceFromCommon } from \"@botbotgo/common/utils\";\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 applyDefaultToolChoiceFromCommon(model);\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 \"@botbotgo/common/connectivity\";\nimport { parseLlmSection } from \"../model/llm-parser.js\";\nimport type { LLMConfig } from \"../model/types.js\";\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 resolveHost =\n opts?.resolveHost != null && typeof (opts.resolveHost as { from?: string; to?: string }).from === \"string\"\n ? (opts.resolveHost as { from: string; to: string })\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":[]}
|
package/dist/cli/index.js
CHANGED
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/api/create-agent-llm.ts","../../src/cli/utils.ts","../../src/cli/index.ts"],"sourcesContent":["/**\n * Simple API: create LangChain ChatModel from model.yaml config.\n * Supports OpenAI-compatible providers with optional connectivity check and npm: provider resolution.\n */\nimport { join } from \"node:path\";\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport type { ConnectionStatus } from \"@easynet/agent-common/connectivity\";\nimport { createChatModelFromLlmConfig } from \"../langchain/index.js\";\nimport { resolveLlmSectionWithNpm } from \"../extensions/npm-protocol.js\";\nimport { loadModelConfig } from \"../config/loader.js\";\nimport { applyDefaultToolChoice } from \"./chat-model.js\";\nimport { ensureConnectivity } from \"./connectivity.js\";\n\nexport interface CreateAgentLlmOptions {\n configPath?: string;\n installNpmIfMissing?: boolean;\n checkConnectivity?: boolean;\n onConnectionStatus?: (status: ConnectionStatus) => void;\n connectivityTimeoutMs?: number;\n}\n\nfunction resolveDefaultConfigPath(): string {\n return join(process.cwd(), \"model.yaml\");\n}\n\nfunction normalizeOptions(\n configPathOrOptions?: string | CreateAgentLlmOptions\n): CreateAgentLlmOptions {\n if (configPathOrOptions == null) return {};\n if (typeof configPathOrOptions === \"string\") return { configPath: configPathOrOptions };\n return configPathOrOptions;\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\n/**\n * Create a LangChain ChatModel from model.yaml config.\n * Returns BaseChatModel compatible with LangChain's createAgent and other tools.\n */\nexport async function createAgentLlm(\n configPathOrOptions?: string | CreateAgentLlmOptions\n): Promise<BaseChatModel> {\n try {\n const options = normalizeOptions(configPathOrOptions);\n const configPath = options.configPath ?? resolveDefaultConfigPath();\n const modelConfig = loadModelConfig(configPath);\n\n if (modelConfig?.llm == null) {\n throw new Error(\n `No LLM config at ${configPath}. Add model.yaml in the current directory, or pass configPath.`\n );\n }\n\n const resolvedSection = await resolveLlmSectionWithNpm(modelConfig.llm, {\n installNpmIfMissing: options.installNpmIfMissing !== false,\n cwd: process.cwd(),\n });\n\n // Priority: caller option > YAML runtime > default (true)\n const checkConnectivity =\n options.checkConnectivity ?? modelConfig.runtime.check_connectivity;\n\n await ensureConnectivity(resolvedSection, {\n checkConnectivity,\n onConnectionStatus: options.onConnectionStatus,\n connectivityTimeoutMs: options.connectivityTimeoutMs,\n });\n\n const model = createChatModelFromLlmConfig({ llmSection: resolvedSection });\n applyDefaultToolChoice(model);\n return model;\n } catch (e) {\n if (e instanceof Error && e.message.includes(\"No LLM config\")) throw e;\n if (e instanceof Error && e.message.includes(\"Cannot connect to\")) throw e;\n throw normalizeError(e, \"createAgentLlm failed\");\n }\n}\n","/**\n * Shared CLI helpers for agent-model and provider CLIs.\n */\n\n/**\n * Turn LangChain message content (string | array of parts) into a single string.\n */\nexport function messageContentToString(content: unknown): string {\n if (typeof content === \"string\") return content;\n if (Array.isArray(content)) {\n return (content as { type?: string; text?: string }[])\n .map((c) => (\"text\" in c && c.text ? c.text : \"\"))\n .join(\"\");\n }\n return String(content ?? \"\");\n}\n\n/**\n * Log error and exit. Use in CLIs for consistent error handling.\n */\nexport function exitWithError(err: unknown, code = 1): never {\n console.error(\"Error:\", err instanceof Error ? err.message : String(err));\n process.exit(code);\n}\n","#!/usr/bin/env node\n/**\n * CLI for @easynet/agent-model: chat with the configured LLM (LangChain ChatOpenAI).\n * Usage: agent-model \"your question\"\n * or: agent-model --config ./model.yaml \"hi\"\n * or: agent-model --tools \"what is the weather in SF?\"\n */\nimport { createAgentLlm } from \"../api/create-agent-llm.js\";\nimport { messageContentToString } from \"./utils.js\";\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { HumanMessage, AIMessage, ToolMessage } from \"@langchain/core/messages\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport { fileURLToPath } from \"node:url\";\n\nfunction parseArgv(): { configPath: string | undefined; useTools: boolean; query: string } {\n const args = process.argv.slice(2);\n let configPath: string | undefined;\n let useTools = false;\n const rest: string[] = [];\n for (let i = 0; i < args.length; i++) {\n if (args[i] === \"--config\" && args[i + 1]) {\n configPath = args[i + 1];\n i++;\n } else if (args[i] === \"--tools\") {\n useTools = true;\n } else {\n rest.push(args[i]);\n }\n }\n const query = rest.join(\" \").trim() || \"hi\";\n return { configPath, useTools, query };\n}\n\nconst getWeather = tool(\n (input: { location: string }) => {\n const loc = input.location.toLowerCase();\n if ([\"sf\", \"sf bay\"].includes(loc)) return \"It's 60°F and foggy in the Bay Area.\";\n if ([\"ny\", \"new york\"].includes(loc)) return \"It's 72°F and partly cloudy in New York.\";\n return `Weather for ${input.location}: 70°F and sunny.`;\n },\n {\n name: \"get_weather\",\n description: \"Get the current weather for a location.\",\n schema: z.object({\n location: z.string().describe(\"City or place name (e.g. SF, New York)\"),\n }),\n }\n);\n\nconst addNumbers = tool(\n (input: { a: number; b: number }) => String(input.a + input.b),\n {\n name: \"add_numbers\",\n description: \"Add two numbers.\",\n schema: z.object({\n a: z.number().describe(\"First number\"),\n b: z.number().describe(\"Second number\"),\n }),\n }\n);\n\nconst tools = [getWeather, addNumbers];\nconst toolsByName = new Map(tools.map((t) => [t.name, t]));\nconst MAX_TURNS = 10;\n\nasync function runSimpleChat(model: BaseChatModel, query: string): Promise<string> {\n const messages: BaseMessage[] = [new HumanMessage(query)];\n const response = await model.invoke(messages);\n return messageContentToString(response.content);\n}\n\nasync function runAgentWithTools(model: BaseChatModel, query: string): Promise<string> {\n const withTools = model.bindTools?.(tools, { tool_choice: \"auto\" });\n const messages: BaseMessage[] = [new HumanMessage(query)];\n if (!withTools) return runSimpleChat(model, query);\n\n for (let turn = 0; turn < MAX_TURNS; turn++) {\n const response = await withTools.invoke(messages);\n const aiMessage = response as AIMessage;\n\n if (!aiMessage.tool_calls?.length) {\n return messageContentToString(aiMessage.content);\n }\n\n messages.push(aiMessage);\n for (const tc of aiMessage.tool_calls) {\n const id = tc.id ?? `call_${turn}_${tc.name}`;\n const toolFn = toolsByName.get(tc.name as \"get_weather\" | \"add_numbers\");\n let result: string;\n if (toolFn) {\n try {\n const out = await (toolFn as { invoke: (args: Record<string, unknown>) => Promise<unknown> }).invoke(\n tc.args as Record<string, unknown>\n );\n result = typeof out === \"string\" ? out : JSON.stringify(out);\n } catch (err) {\n result = `Error: ${err instanceof Error ? err.message : String(err)}`;\n }\n } else {\n result = `Unknown tool: ${tc.name}`;\n }\n messages.push(new ToolMessage({ content: result, tool_call_id: id }));\n }\n }\n return \"Agent reached max turns without a final answer.\";\n}\n\nasync function main() {\n const { configPath, useTools, query } = parseArgv();\n const model = await createAgentLlm(configPath ? { configPath } : undefined);\n\n console.log(\"Query:\", query);\n console.log(\"---\");\n const answer = useTools\n ? await runAgentWithTools(model, query)\n : await runSimpleChat(model, query);\n console.log(\"Answer:\", answer);\n console.log(\"---\");\n console.log(\"Done.\");\n}\n\nconst entryArg = process.argv[1];\nconst isDirectRun =\n typeof entryArg === \"string\" && entryArg.length > 0 && fileURLToPath(import.meta.url) === entryArg;\n\nif (isDirectRun) {\n main().catch((err) => {\n console.error(err);\n process.exit(1);\n });\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/api/create-agent-llm.ts","../../src/cli/utils.ts","../../src/cli/index.ts"],"sourcesContent":["/**\n * Simple API: create LangChain ChatModel from model.yaml config.\n * Supports OpenAI-compatible providers with optional connectivity check and npm: provider resolution.\n */\nimport { join } from \"node:path\";\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport type { ConnectionStatus } from \"@botbotgo/common/connectivity\";\nimport { createChatModelFromLlmConfig } from \"../langchain/index.js\";\nimport { resolveLlmSectionWithNpm } from \"../extensions/npm-protocol.js\";\nimport { loadModelConfig } from \"../config/loader.js\";\nimport { applyDefaultToolChoice } from \"./chat-model.js\";\nimport { ensureConnectivity } from \"./connectivity.js\";\n\nexport interface CreateAgentLlmOptions {\n configPath?: string;\n installNpmIfMissing?: boolean;\n checkConnectivity?: boolean;\n onConnectionStatus?: (status: ConnectionStatus) => void;\n connectivityTimeoutMs?: number;\n}\n\nfunction resolveDefaultConfigPath(): string {\n return join(process.cwd(), \"model.yaml\");\n}\n\nfunction normalizeOptions(\n configPathOrOptions?: string | CreateAgentLlmOptions\n): CreateAgentLlmOptions {\n if (configPathOrOptions == null) return {};\n if (typeof configPathOrOptions === \"string\") return { configPath: configPathOrOptions };\n return configPathOrOptions;\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\n/**\n * Create a LangChain ChatModel from model.yaml config.\n * Returns BaseChatModel compatible with LangChain's createAgent and other tools.\n */\nexport async function createAgentLlm(\n configPathOrOptions?: string | CreateAgentLlmOptions\n): Promise<BaseChatModel> {\n try {\n const options = normalizeOptions(configPathOrOptions);\n const configPath = options.configPath ?? resolveDefaultConfigPath();\n const modelConfig = loadModelConfig(configPath);\n\n if (modelConfig?.llm == null) {\n throw new Error(\n `No LLM config at ${configPath}. Add model.yaml in the current directory, or pass configPath.`\n );\n }\n\n const resolvedSection = await resolveLlmSectionWithNpm(modelConfig.llm, {\n installNpmIfMissing: options.installNpmIfMissing !== false,\n cwd: process.cwd(),\n });\n\n // Priority: caller option > YAML runtime > default (true)\n const checkConnectivity =\n options.checkConnectivity ?? modelConfig.runtime.check_connectivity;\n\n await ensureConnectivity(resolvedSection, {\n checkConnectivity,\n onConnectionStatus: options.onConnectionStatus,\n connectivityTimeoutMs: options.connectivityTimeoutMs,\n });\n\n const model = createChatModelFromLlmConfig({ llmSection: resolvedSection });\n applyDefaultToolChoice(model);\n return model;\n } catch (e) {\n if (e instanceof Error && e.message.includes(\"No LLM config\")) throw e;\n if (e instanceof Error && e.message.includes(\"Cannot connect to\")) throw e;\n throw normalizeError(e, \"createAgentLlm failed\");\n }\n}\n","/**\n * Shared CLI helpers for agent-model and provider CLIs.\n */\n\n/**\n * Turn LangChain message content (string | array of parts) into a single string.\n */\nexport function messageContentToString(content: unknown): string {\n if (typeof content === \"string\") return content;\n if (Array.isArray(content)) {\n return (content as { type?: string; text?: string }[])\n .map((c) => (\"text\" in c && c.text ? c.text : \"\"))\n .join(\"\");\n }\n return String(content ?? \"\");\n}\n\n/**\n * Log error and exit. Use in CLIs for consistent error handling.\n */\nexport function exitWithError(err: unknown, code = 1): never {\n console.error(\"Error:\", err instanceof Error ? err.message : String(err));\n process.exit(code);\n}\n","#!/usr/bin/env node\n/**\n * CLI for @botbotgo/model: chat with the configured LLM (LangChain ChatOpenAI).\n * Usage: agent-model \"your question\"\n * or: agent-model --config ./model.yaml \"hi\"\n * or: agent-model --tools \"what is the weather in SF?\"\n */\nimport { createAgentLlm } from \"../api/create-agent-llm.js\";\nimport { messageContentToString } from \"./utils.js\";\nimport type { BaseChatModel } from \"@langchain/core/language_models/chat_models\";\nimport { tool } from \"@langchain/core/tools\";\nimport { z } from \"zod\";\nimport { HumanMessage, AIMessage, ToolMessage } from \"@langchain/core/messages\";\nimport type { BaseMessage } from \"@langchain/core/messages\";\nimport { fileURLToPath } from \"node:url\";\n\nfunction parseArgv(): { configPath: string | undefined; useTools: boolean; query: string } {\n const args = process.argv.slice(2);\n let configPath: string | undefined;\n let useTools = false;\n const rest: string[] = [];\n for (let i = 0; i < args.length; i++) {\n if (args[i] === \"--config\" && args[i + 1]) {\n configPath = args[i + 1];\n i++;\n } else if (args[i] === \"--tools\") {\n useTools = true;\n } else {\n rest.push(args[i]);\n }\n }\n const query = rest.join(\" \").trim() || \"hi\";\n return { configPath, useTools, query };\n}\n\nconst getWeather = tool(\n (input: { location: string }) => {\n const loc = input.location.toLowerCase();\n if ([\"sf\", \"sf bay\"].includes(loc)) return \"It's 60°F and foggy in the Bay Area.\";\n if ([\"ny\", \"new york\"].includes(loc)) return \"It's 72°F and partly cloudy in New York.\";\n return `Weather for ${input.location}: 70°F and sunny.`;\n },\n {\n name: \"get_weather\",\n description: \"Get the current weather for a location.\",\n schema: z.object({\n location: z.string().describe(\"City or place name (e.g. SF, New York)\"),\n }),\n }\n);\n\nconst addNumbers = tool(\n (input: { a: number; b: number }) => String(input.a + input.b),\n {\n name: \"add_numbers\",\n description: \"Add two numbers.\",\n schema: z.object({\n a: z.number().describe(\"First number\"),\n b: z.number().describe(\"Second number\"),\n }),\n }\n);\n\nconst tools = [getWeather, addNumbers];\nconst toolsByName = new Map(tools.map((t) => [t.name, t]));\nconst MAX_TURNS = 10;\n\nasync function runSimpleChat(model: BaseChatModel, query: string): Promise<string> {\n const messages: BaseMessage[] = [new HumanMessage(query)];\n const response = await model.invoke(messages);\n return messageContentToString(response.content);\n}\n\nasync function runAgentWithTools(model: BaseChatModel, query: string): Promise<string> {\n const withTools = model.bindTools?.(tools, { tool_choice: \"auto\" });\n const messages: BaseMessage[] = [new HumanMessage(query)];\n if (!withTools) return runSimpleChat(model, query);\n\n for (let turn = 0; turn < MAX_TURNS; turn++) {\n const response = await withTools.invoke(messages);\n const aiMessage = response as AIMessage;\n\n if (!aiMessage.tool_calls?.length) {\n return messageContentToString(aiMessage.content);\n }\n\n messages.push(aiMessage);\n for (const tc of aiMessage.tool_calls) {\n const id = tc.id ?? `call_${turn}_${tc.name}`;\n const toolFn = toolsByName.get(tc.name as \"get_weather\" | \"add_numbers\");\n let result: string;\n if (toolFn) {\n try {\n const out = await (toolFn as { invoke: (args: Record<string, unknown>) => Promise<unknown> }).invoke(\n tc.args as Record<string, unknown>\n );\n result = typeof out === \"string\" ? out : JSON.stringify(out);\n } catch (err) {\n result = `Error: ${err instanceof Error ? err.message : String(err)}`;\n }\n } else {\n result = `Unknown tool: ${tc.name}`;\n }\n messages.push(new ToolMessage({ content: result, tool_call_id: id }));\n }\n }\n return \"Agent reached max turns without a final answer.\";\n}\n\nasync function main() {\n const { configPath, useTools, query } = parseArgv();\n const model = await createAgentLlm(configPath ? { configPath } : undefined);\n\n console.log(\"Query:\", query);\n console.log(\"---\");\n const answer = useTools\n ? await runAgentWithTools(model, query)\n : await runSimpleChat(model, query);\n console.log(\"Answer:\", answer);\n console.log(\"---\");\n console.log(\"Done.\");\n}\n\nconst entryArg = process.argv[1];\nconst isDirectRun =\n typeof entryArg === \"string\" && entryArg.length > 0 && fileURLToPath(import.meta.url) === entryArg;\n\nif (isDirectRun) {\n main().catch((err) => {\n console.error(err);\n process.exit(1);\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAIA,SAAS,YAAY;AAiBrB,SAAS,2BAAmC;AAC1C,SAAO,KAAK,QAAQ,IAAI,GAAG,YAAY;AACzC;AAEA,SAAS,iBACP,qBACuB;AACvB,MAAI,uBAAuB,KAAM,QAAO,CAAC;AACzC,MAAI,OAAO,wBAAwB,SAAU,QAAO,EAAE,YAAY,oBAAoB;AACtF,SAAO;AACT;AAEA,SAAS,eAAe,GAAY,SAAwB;AAC1D,MAAI,aAAa,MAAO,QAAO,IAAI,MAAM,GAAG,OAAO,KAAK,EAAE,OAAO,IAAI,EAAE,OAAO,EAAE,CAAC;AACjF,SAAO,IAAI,MAAM,GAAG,OAAO,KAAK,OAAO,CAAC,CAAC,EAAE;AAC7C;AAMA,eAAsB,eACpB,qBACwB;AACxB,MAAI;AACF,UAAM,UAAU,iBAAiB,mBAAmB;AACpD,UAAM,aAAa,QAAQ,cAAc,yBAAyB;AAClE,UAAM,cAAc,gBAAgB,UAAU;AAE9C,QAAI,aAAa,OAAO,MAAM;AAC5B,YAAM,IAAI;AAAA,QACR,oBAAoB,UAAU;AAAA,MAChC;AAAA,IACF;AAEA,UAAM,kBAAkB,MAAM,yBAAyB,YAAY,KAAK;AAAA,MACtE,qBAAqB,QAAQ,wBAAwB;AAAA,MACrD,KAAK,QAAQ,IAAI;AAAA,IACnB,CAAC;AAGD,UAAM,oBACJ,QAAQ,qBAAqB,YAAY,QAAQ;AAEnD,UAAM,mBAAmB,iBAAiB;AAAA,MACxC;AAAA,MACA,oBAAoB,QAAQ;AAAA,MAC5B,uBAAuB,QAAQ;AAAA,IACjC,CAAC;AAED,UAAM,QAAQ,6BAA6B,EAAE,YAAY,gBAAgB,CAAC;AAC1E,2BAAuB,KAAK;AAC5B,WAAO;AAAA,EACT,SAAS,GAAG;AACV,QAAI,aAAa,SAAS,EAAE,QAAQ,SAAS,eAAe,EAAG,OAAM;AACrE,QAAI,aAAa,SAAS,EAAE,QAAQ,SAAS,mBAAmB,EAAG,OAAM;AACzE,UAAM,eAAe,GAAG,uBAAuB;AAAA,EACjD;AACF;;;ACxEO,SAAS,uBAAuB,SAA0B;AAC/D,MAAI,OAAO,YAAY,SAAU,QAAO;AACxC,MAAI,MAAM,QAAQ,OAAO,GAAG;AAC1B,WAAQ,QACL,IAAI,CAAC,MAAO,UAAU,KAAK,EAAE,OAAO,EAAE,OAAO,EAAG,EAChD,KAAK,EAAE;AAAA,EACZ;AACA,SAAO,OAAO,WAAW,EAAE;AAC7B;;;ACLA,SAAS,YAAY;AACrB,SAAS,SAAS;AAClB,SAAS,cAAyB,mBAAmB;AAErD,SAAS,qBAAqB;AAE9B,SAAS,YAAkF;AACzF,QAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;AACjC,MAAI;AACJ,MAAI,WAAW;AACf,QAAM,OAAiB,CAAC;AACxB,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,QAAI,KAAK,CAAC,MAAM,cAAc,KAAK,IAAI,CAAC,GAAG;AACzC,mBAAa,KAAK,IAAI,CAAC;AACvB;AAAA,IACF,WAAW,KAAK,CAAC,MAAM,WAAW;AAChC,iBAAW;AAAA,IACb,OAAO;AACL,WAAK,KAAK,KAAK,CAAC,CAAC;AAAA,IACnB;AAAA,EACF;AACA,QAAM,QAAQ,KAAK,KAAK,GAAG,EAAE,KAAK,KAAK;AACvC,SAAO,EAAE,YAAY,UAAU,MAAM;AACvC;AAEA,IAAM,aAAa;AAAA,EACjB,CAAC,UAAgC;AAC/B,UAAM,MAAM,MAAM,SAAS,YAAY;AACvC,QAAI,CAAC,MAAM,QAAQ,EAAE,SAAS,GAAG,EAAG,QAAO;AAC3C,QAAI,CAAC,MAAM,UAAU,EAAE,SAAS,GAAG,EAAG,QAAO;AAC7C,WAAO,eAAe,MAAM,QAAQ;AAAA,EACtC;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ,EAAE,OAAO;AAAA,MACf,UAAU,EAAE,OAAO,EAAE,SAAS,wCAAwC;AAAA,IACxE,CAAC;AAAA,EACH;AACF;AAEA,IAAM,aAAa;AAAA,EACjB,CAAC,UAAoC,OAAO,MAAM,IAAI,MAAM,CAAC;AAAA,EAC7D;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,QAAQ,EAAE,OAAO;AAAA,MACf,GAAG,EAAE,OAAO,EAAE,SAAS,cAAc;AAAA,MACrC,GAAG,EAAE,OAAO,EAAE,SAAS,eAAe;AAAA,IACxC,CAAC;AAAA,EACH;AACF;AAEA,IAAM,QAAQ,CAAC,YAAY,UAAU;AACrC,IAAM,cAAc,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AACzD,IAAM,YAAY;AAElB,eAAe,cAAc,OAAsB,OAAgC;AACjF,QAAM,WAA0B,CAAC,IAAI,aAAa,KAAK,CAAC;AACxD,QAAM,WAAW,MAAM,MAAM,OAAO,QAAQ;AAC5C,SAAO,uBAAuB,SAAS,OAAO;AAChD;AAEA,eAAe,kBAAkB,OAAsB,OAAgC;AACrF,QAAM,YAAY,MAAM,YAAY,OAAO,EAAE,aAAa,OAAO,CAAC;AAClE,QAAM,WAA0B,CAAC,IAAI,aAAa,KAAK,CAAC;AACxD,MAAI,CAAC,UAAW,QAAO,cAAc,OAAO,KAAK;AAEjD,WAAS,OAAO,GAAG,OAAO,WAAW,QAAQ;AAC3C,UAAM,WAAW,MAAM,UAAU,OAAO,QAAQ;AAChD,UAAM,YAAY;AAElB,QAAI,CAAC,UAAU,YAAY,QAAQ;AACjC,aAAO,uBAAuB,UAAU,OAAO;AAAA,IACjD;AAEA,aAAS,KAAK,SAAS;AACvB,eAAW,MAAM,UAAU,YAAY;AACrC,YAAM,KAAK,GAAG,MAAM,QAAQ,IAAI,IAAI,GAAG,IAAI;AAC3C,YAAM,SAAS,YAAY,IAAI,GAAG,IAAqC;AACvE,UAAI;AACJ,UAAI,QAAQ;AACV,YAAI;AACF,gBAAM,MAAM,MAAO,OAA2E;AAAA,YAC5F,GAAG;AAAA,UACL;AACA,mBAAS,OAAO,QAAQ,WAAW,MAAM,KAAK,UAAU,GAAG;AAAA,QAC7D,SAAS,KAAK;AACZ,mBAAS,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA,QACrE;AAAA,MACF,OAAO;AACL,iBAAS,iBAAiB,GAAG,IAAI;AAAA,MACnC;AACA,eAAS,KAAK,IAAI,YAAY,EAAE,SAAS,QAAQ,cAAc,GAAG,CAAC,CAAC;AAAA,IACtE;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAe,OAAO;AACpB,QAAM,EAAE,YAAY,UAAU,MAAM,IAAI,UAAU;AAClD,QAAM,QAAQ,MAAM,eAAe,aAAa,EAAE,WAAW,IAAI,MAAS;AAE1E,UAAQ,IAAI,UAAU,KAAK;AAC3B,UAAQ,IAAI,KAAK;AACjB,QAAM,SAAS,WACX,MAAM,kBAAkB,OAAO,KAAK,IACpC,MAAM,cAAc,OAAO,KAAK;AACpC,UAAQ,IAAI,WAAW,MAAM;AAC7B,UAAQ,IAAI,KAAK;AACjB,UAAQ,IAAI,OAAO;AACrB;AAEA,IAAM,WAAW,QAAQ,KAAK,CAAC;AAC/B,IAAM,cACJ,OAAO,aAAa,YAAY,SAAS,SAAS,KAAK,cAAc,YAAY,GAAG,MAAM;AAE5F,IAAI,aAAa;AACf,OAAK,EAAE,MAAM,CAAC,QAAQ;AACpB,YAAQ,MAAM,GAAG;AACjB,YAAQ,KAAK,CAAC;AAAA,EAChB,CAAC;AACH;","names":[]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { loadYamlFile, loadYamlFileSync, parseYamlContent, clearYamlFileCache, } from "@
|
|
2
|
-
export type { LoadYamlOptions } from "@
|
|
1
|
+
export { loadYamlFile, loadYamlFileSync, parseYamlContent, clearYamlFileCache, } from "@botbotgo/common/config";
|
|
2
|
+
export type { LoadYamlOptions } from "@botbotgo/common/config";
|
|
3
3
|
export interface YamlEnvOptions {
|
|
4
4
|
substituteEnv?: boolean;
|
|
5
5
|
missingEnv?: "keep" | "empty" | "error";
|
|
@@ -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,GACnB,MAAM,
|
|
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,yBAAyB,CAAC;AAEjC,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,MAAM,WAAW,cAAc;IAC7B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;CACzC"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
applyDefaultToolChoice,
|
|
3
3
|
ensureConnectivity,
|
|
4
4
|
loadModelConfig
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-ZFGQMWFQ.js";
|
|
6
6
|
import {
|
|
7
7
|
resolveLlmSectionWithNpm
|
|
8
8
|
} from "./chunk-73UYN63C.js";
|
|
@@ -18,10 +18,10 @@ import {
|
|
|
18
18
|
import "./chunk-G7MKWPEI.js";
|
|
19
19
|
|
|
20
20
|
// src/api/register-model.ts
|
|
21
|
-
import { AgentContextTokens } from "@
|
|
21
|
+
import { AgentContextTokens } from "@botbotgo/common/context";
|
|
22
22
|
|
|
23
23
|
// src/agent-context.ts
|
|
24
|
-
import { createAgentContext } from "@
|
|
24
|
+
import { createAgentContext } from "@botbotgo/common/context";
|
|
25
25
|
var DEFAULT_CONTEXT_KEY = "__easynet_agent_default_context__";
|
|
26
26
|
function isAgentContext(value) {
|
|
27
27
|
return typeof value === "object" && value !== null && typeof value.get === "function" && typeof value.set === "function" && typeof value.has === "function";
|
|
@@ -40,7 +40,7 @@ import { existsSync } from "fs";
|
|
|
40
40
|
import { dirname, resolve } from "path";
|
|
41
41
|
import { fileURLToPath } from "url";
|
|
42
42
|
import { OpenAIEmbeddings } from "@langchain/openai";
|
|
43
|
-
import { deepMerge } from "@
|
|
43
|
+
import { deepMerge } from "@botbotgo/common/utils";
|
|
44
44
|
function resolveEmbeddedConfigPath() {
|
|
45
45
|
const moduleDir = dirname(fileURLToPath(import.meta.url));
|
|
46
46
|
const candidates = [
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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/context\";\nimport { getDefaultAgentContext } from \"../agent-context.js\";\nimport {\n createAgentModelRegistry,\n type CreateAgentModelRegistryOptions,\n type CreateAgentModelChatOptions,\n} from \"./create-agent-model-registry.js\";\n\nexport interface CreateAgentModelOptions extends CreateAgentModelRegistryOptions, CreateAgentModelChatOptions {}\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(\"config/model.yaml\");\n * ```\n */\nexport async function createAgentModel(configPathOrOptions?: string | CreateAgentModelOptions): Promise<void> {\n const options =\n typeof configPathOrOptions === \"string\" || configPathOrOptions == null\n ? configPathOrOptions\n : { configPath: configPathOrOptions.configPath };\n const chatOptions =\n typeof configPathOrOptions === \"string\" || configPathOrOptions == null\n ? undefined\n : {\n installNpmIfMissing: configPathOrOptions.installNpmIfMissing,\n checkConnectivity: configPathOrOptions.checkConnectivity,\n onConnectionStatus: configPathOrOptions.onConnectionStatus,\n connectivityTimeoutMs: configPathOrOptions.connectivityTimeoutMs,\n };\n const registry = await createAgentModelRegistry(options);\n const llm = await registry.getChatModel(chatOptions);\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(chatOptions);\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/context\";\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 } from \"@easynet/agent-common/utils\";\nimport type { ConnectionStatus } from \"@easynet/agent-common/connectivity\";\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 \"@botbotgo/common/context\";\nimport { getDefaultAgentContext } from \"../agent-context.js\";\nimport {\n createAgentModelRegistry,\n type CreateAgentModelRegistryOptions,\n type CreateAgentModelChatOptions,\n} from \"./create-agent-model-registry.js\";\n\nexport interface CreateAgentModelOptions extends CreateAgentModelRegistryOptions, CreateAgentModelChatOptions {}\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(\"config/model.yaml\");\n * ```\n */\nexport async function createAgentModel(configPathOrOptions?: string | CreateAgentModelOptions): Promise<void> {\n const options =\n typeof configPathOrOptions === \"string\" || configPathOrOptions == null\n ? configPathOrOptions\n : { configPath: configPathOrOptions.configPath };\n const chatOptions =\n typeof configPathOrOptions === \"string\" || configPathOrOptions == null\n ? undefined\n : {\n installNpmIfMissing: configPathOrOptions.installNpmIfMissing,\n checkConnectivity: configPathOrOptions.checkConnectivity,\n onConnectionStatus: configPathOrOptions.onConnectionStatus,\n connectivityTimeoutMs: configPathOrOptions.connectivityTimeoutMs,\n };\n const registry = await createAgentModelRegistry(options);\n const llm = await registry.getChatModel(chatOptions);\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(chatOptions);\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 \"@botbotgo/common/context\";\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 } from \"@botbotgo/common/utils\";\nimport type { ConnectionStatus } from \"@botbotgo/common/connectivity\";\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":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@easynet/agent-model",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.90",
|
|
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": {
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"typecheck": "tsc --noEmit"
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@
|
|
30
|
+
"@botbotgo/common": "latest",
|
|
31
31
|
"axios": "^1.7.0",
|
|
32
32
|
"yaml": "^2.7.0",
|
|
33
33
|
"zod": "^3.23.0"
|
|
@@ -59,7 +59,11 @@
|
|
|
59
59
|
},
|
|
60
60
|
"repository": {
|
|
61
61
|
"type": "git",
|
|
62
|
-
"url": "
|
|
62
|
+
"url": "https://github.com/easynet-world/agent-model.git"
|
|
63
|
+
},
|
|
64
|
+
"homepage": "https://github.com/easynet-world/agent-model#readme",
|
|
65
|
+
"bugs": {
|
|
66
|
+
"url": "https://github.com/easynet-world/agent-model/issues"
|
|
63
67
|
},
|
|
64
68
|
"engines": {
|
|
65
69
|
"node": ">=18.0.0"
|
|
@@ -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} from \"@easynet/agent-common/config\";\n\nexport type { LoadYamlOptions } from \"@easynet/agent-common/config\";\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 { applyDefaultToolChoice as applyDefaultToolChoiceFromCommon } from \"@easynet/agent-common/utils\";\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 applyDefaultToolChoiceFromCommon(model);\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/connectivity\";\nimport { parseLlmSection } from \"../model/llm-parser.js\";\nimport type { LLMConfig } from \"../model/types.js\";\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 resolveHost =\n opts?.resolveHost != null && typeof (opts.resolveHost as { from?: string; to?: string }).from === \"string\"\n ? (opts.resolveHost as { from: string; to: string })\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":[]}
|