akm-cli
Version:
akm (Agent Knowledge Manager) — a portable, local-first capability library for AI agents. Discover, load, share, and improve reusable skills, scripts, workflows, and knowledge across any shell-capable coding agent, including Claude Code, OpenCode, and Cur
98 lines (97 loc) • 4.24 kB
JavaScript
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
import { ConfigError } from "../core/errors.js";
export function readCurrentLlmEngine(config) {
const name = config.defaults?.llmEngine;
const engine = name ? config.engines?.[name] : undefined;
if (!engine || engine.kind !== "llm")
return undefined;
const { kind: _kind, timeoutMs, ...connection } = engine;
return {
...connection,
...(timeoutMs !== undefined ? { timeoutMs } : {}),
};
}
export function readAgentEngineSelection(config) {
const engines = {};
for (const [name, engine] of Object.entries(config.engines ?? {})) {
if (engine.kind === "agent")
engines[name] = { ...engine };
}
const defaultName = config.defaults?.engine;
const defaultIsAgent = defaultName && config.engines?.[defaultName]?.kind === "agent";
if (Object.keys(engines).length === 0 && !defaultIsAgent)
return undefined;
return { ...(defaultIsAgent ? { default: defaultName } : {}), engines };
}
/** Write an OpenAI-compatible connection as a named LLM engine. */
export function writeLlmEngine(config, llm) {
const name = config.defaults?.llmEngine ?? "default";
if (!llm) {
const engines = { ...(config.engines ?? {}) };
if (engines[name]?.kind === "llm")
delete engines[name];
const defaults = { ...(config.defaults ?? {}) };
delete defaults.llmEngine;
if (defaults.engine === name)
delete defaults.engine;
return { engines, defaults };
}
if (config.engines?.[name] && config.engines[name].kind !== "llm") {
throw new ConfigError(`Cannot configure LLM engine ${JSON.stringify(name)} because that name belongs to an agent engine.`, "INVALID_CONFIG_FILE");
}
const endpoint = llm.endpoint.endsWith("/chat/completions")
? llm.endpoint
: `${llm.endpoint.replace(/\/$/, "")}/chat/completions`;
return {
engines: {
...(config.engines ?? {}),
[name]: {
...llm,
kind: "llm",
endpoint,
},
},
defaults: { ...(config.defaults ?? {}), engine: config.defaults?.engine ?? name, llmEngine: name },
};
}
/** Merge setup-selected agent engines without translating profile-shaped data. */
export function writeAgentEngines(config, selection) {
for (const [name, engine] of Object.entries(selection?.engines ?? {})) {
const existing = config.engines?.[name];
if (existing && existing.kind !== engine.kind) {
throw new ConfigError(`Cannot configure ${engine.kind} engine ${JSON.stringify(name)} because that name belongs to an ${existing.kind} engine.`, "INVALID_CONFIG_FILE");
}
}
const defaults = { ...(config.defaults ?? {}) };
if (selection?.disabled) {
const currentDefault = defaults.engine;
if (currentDefault && config.engines?.[currentDefault]?.kind === "agent") {
const llmDefault = defaults.llmEngine;
if (llmDefault && config.engines?.[llmDefault]?.kind === "llm")
defaults.engine = llmDefault;
else
delete defaults.engine;
}
}
if (selection?.default)
defaults.engine = selection.default;
const engines = { ...(config.engines ?? {}), ...(selection?.engines ?? {}) };
const selectedEngine = selection?.default ? engines[selection.default] : undefined;
if (selection?.default && selectedEngine && selectedEngine.kind !== "agent") {
throw new ConfigError(`Cannot select agent engine ${JSON.stringify(selection.default)} because that name belongs to an LLM engine.`, "INVALID_CONFIG_FILE");
}
if (selection?.default && !engines[selection.default]) {
engines[selection.default] = {
kind: "agent",
platform: selection.default,
};
}
return { engines, defaults };
}
export function cloneLlmConnection(llm) {
if (!llm)
return undefined;
return JSON.parse(JSON.stringify(llm));
}