mindkeeper-openclaw 0.2.6 → 0.2.7
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/dist/index.js +93 -225
- package/dist/llm-client.js +118 -0
- package/package.json +1 -1
- package/skills/mindkeeper/SKILL.md +0 -4
package/dist/index.js
CHANGED
|
@@ -10,16 +10,9 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
10
10
|
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
11
11
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
12
12
|
});
|
|
13
|
-
var __esm = (fn, res) => function __init() {
|
|
14
|
-
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
15
|
-
};
|
|
16
13
|
var __commonJS = (cb, mod) => function __require2() {
|
|
17
14
|
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
18
15
|
};
|
|
19
|
-
var __export = (target, all) => {
|
|
20
|
-
for (var name in all)
|
|
21
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
22
|
-
};
|
|
23
16
|
var __copyProps = (to, from, except, desc) => {
|
|
24
17
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
25
18
|
for (let key of __getOwnPropNames(from))
|
|
@@ -15094,7 +15087,7 @@ ${obj.gpgsig ? obj.gpgsig : ""}`;
|
|
|
15094
15087
|
throw err;
|
|
15095
15088
|
}
|
|
15096
15089
|
}
|
|
15097
|
-
async function
|
|
15090
|
+
async function fetch({
|
|
15098
15091
|
fs: fs2,
|
|
15099
15092
|
http,
|
|
15100
15093
|
onProgress,
|
|
@@ -18301,7 +18294,7 @@ ${obj.gpgsig ? obj.gpgsig : ""}`;
|
|
|
18301
18294
|
expandOid,
|
|
18302
18295
|
expandRef,
|
|
18303
18296
|
fastForward,
|
|
18304
|
-
fetch
|
|
18297
|
+
fetch,
|
|
18305
18298
|
findMergeBase,
|
|
18306
18299
|
findRoot,
|
|
18307
18300
|
getRemoteInfo,
|
|
@@ -18371,7 +18364,7 @@ ${obj.gpgsig ? obj.gpgsig : ""}`;
|
|
|
18371
18364
|
exports.expandOid = expandOid;
|
|
18372
18365
|
exports.expandRef = expandRef;
|
|
18373
18366
|
exports.fastForward = fastForward;
|
|
18374
|
-
exports.fetch =
|
|
18367
|
+
exports.fetch = fetch;
|
|
18375
18368
|
exports.findMergeBase = findMergeBase;
|
|
18376
18369
|
exports.findRoot = findRoot;
|
|
18377
18370
|
exports.getConfig = getConfig;
|
|
@@ -18423,218 +18416,6 @@ ${obj.gpgsig ? obj.gpgsig : ""}`;
|
|
|
18423
18416
|
}
|
|
18424
18417
|
});
|
|
18425
18418
|
|
|
18426
|
-
// src/auth-resolver.ts
|
|
18427
|
-
import fsPromises5 from "node:fs/promises";
|
|
18428
|
-
import path6 from "node:path";
|
|
18429
|
-
import os2 from "node:os";
|
|
18430
|
-
function normalizeProvider(provider) {
|
|
18431
|
-
return provider.toLowerCase().replace(/-/g, "").replace(/_/g, "");
|
|
18432
|
-
}
|
|
18433
|
-
async function resolveApiKey(provider) {
|
|
18434
|
-
const profileKey = await readAuthProfileKey(provider);
|
|
18435
|
-
if (profileKey) return profileKey;
|
|
18436
|
-
return readEnvApiKey(provider);
|
|
18437
|
-
}
|
|
18438
|
-
async function readAuthProfileKey(provider) {
|
|
18439
|
-
const candidates = buildAuthProfilePaths();
|
|
18440
|
-
for (const filepath of candidates) {
|
|
18441
|
-
try {
|
|
18442
|
-
const content = await fsPromises5.readFile(filepath, "utf-8");
|
|
18443
|
-
const store = JSON.parse(content);
|
|
18444
|
-
if (!store.profiles || typeof store.profiles !== "object") continue;
|
|
18445
|
-
const normalized = normalizeProvider(provider);
|
|
18446
|
-
for (const credential of Object.values(store.profiles)) {
|
|
18447
|
-
if (normalizeProvider(credential.provider) !== normalized) continue;
|
|
18448
|
-
if (credential.type === "api_key" && credential.key) {
|
|
18449
|
-
return credential.key;
|
|
18450
|
-
}
|
|
18451
|
-
if (credential.type === "token" && credential.token) {
|
|
18452
|
-
return credential.token;
|
|
18453
|
-
}
|
|
18454
|
-
const ref = credential.keyRef ?? credential.tokenRef;
|
|
18455
|
-
if (ref?.source === "env" && ref.key) {
|
|
18456
|
-
const envVal = process.env[ref.key];
|
|
18457
|
-
if (envVal) return envVal;
|
|
18458
|
-
}
|
|
18459
|
-
}
|
|
18460
|
-
} catch {
|
|
18461
|
-
continue;
|
|
18462
|
-
}
|
|
18463
|
-
}
|
|
18464
|
-
return null;
|
|
18465
|
-
}
|
|
18466
|
-
function buildAuthProfilePaths() {
|
|
18467
|
-
const home = os2.homedir();
|
|
18468
|
-
const paths = [];
|
|
18469
|
-
const envHome = process.env.OPENCLAW_HOME;
|
|
18470
|
-
if (envHome) {
|
|
18471
|
-
paths.push(path6.join(envHome, "auth-profiles.json"));
|
|
18472
|
-
}
|
|
18473
|
-
paths.push(
|
|
18474
|
-
path6.join(home, ".openclaw", "auth-profiles.json"),
|
|
18475
|
-
path6.join(home, ".config", "openclaw", "auth-profiles.json")
|
|
18476
|
-
);
|
|
18477
|
-
return paths;
|
|
18478
|
-
}
|
|
18479
|
-
function readEnvApiKey(provider) {
|
|
18480
|
-
const normalized = normalizeProvider(provider);
|
|
18481
|
-
const map = {
|
|
18482
|
-
anthropic: ["ANTHROPIC_API_KEY"],
|
|
18483
|
-
openai: ["OPENAI_API_KEY"],
|
|
18484
|
-
openaicodex: ["OPENAI_API_KEY"],
|
|
18485
|
-
openrouter: ["OPENROUTER_API_KEY"],
|
|
18486
|
-
google: ["GEMINI_API_KEY", "GOOGLE_API_KEY", "GOOGLE_GENERATIVE_AI_API_KEY"],
|
|
18487
|
-
groq: ["GROQ_API_KEY"],
|
|
18488
|
-
mistral: ["MISTRAL_API_KEY"],
|
|
18489
|
-
deepseek: ["DEEPSEEK_API_KEY"],
|
|
18490
|
-
xai: ["XAI_API_KEY"],
|
|
18491
|
-
together: ["TOGETHER_API_KEY"],
|
|
18492
|
-
venice: ["VENICE_API_KEY"],
|
|
18493
|
-
moonshot: ["MOONSHOT_API_KEY"],
|
|
18494
|
-
moonshotcn: ["MOONSHOT_API_KEY"],
|
|
18495
|
-
minimax: ["MINIMAX_API_KEY"],
|
|
18496
|
-
minimaxcn: ["MINIMAX_API_KEY"],
|
|
18497
|
-
zai: ["ZAI_API_KEY", "Z_AI_API_KEY"],
|
|
18498
|
-
qianfan: ["QIANFAN_API_KEY"],
|
|
18499
|
-
volcengine: ["VOLCANO_ENGINE_API_KEY"],
|
|
18500
|
-
byteplus: ["BYTEPLUS_API_KEY"],
|
|
18501
|
-
dashscope: ["DASHSCOPE_API_KEY"],
|
|
18502
|
-
xiaomi: ["XIAOMI_API_KEY"],
|
|
18503
|
-
kilocode: ["KILOCODE_API_KEY"],
|
|
18504
|
-
litellm: ["LITELLM_API_KEY"]
|
|
18505
|
-
};
|
|
18506
|
-
const envKeys = map[normalized] ?? [`${provider.toUpperCase().replace(/-/g, "_")}_API_KEY`];
|
|
18507
|
-
for (const envKey of envKeys) {
|
|
18508
|
-
const val = process.env[envKey];
|
|
18509
|
-
if (val) return val;
|
|
18510
|
-
}
|
|
18511
|
-
return null;
|
|
18512
|
-
}
|
|
18513
|
-
var init_auth_resolver = __esm({
|
|
18514
|
-
"src/auth-resolver.ts"() {
|
|
18515
|
-
"use strict";
|
|
18516
|
-
}
|
|
18517
|
-
});
|
|
18518
|
-
|
|
18519
|
-
// src/llm-client.ts
|
|
18520
|
-
var llm_client_exports = {};
|
|
18521
|
-
__export(llm_client_exports, {
|
|
18522
|
-
callLlm: () => callLlm
|
|
18523
|
-
});
|
|
18524
|
-
async function callLlm(params) {
|
|
18525
|
-
const normalized = normalizeProvider(params.provider);
|
|
18526
|
-
if (normalized === "anthropic") {
|
|
18527
|
-
return callAnthropic(params);
|
|
18528
|
-
}
|
|
18529
|
-
if (normalized === "google") {
|
|
18530
|
-
return callGoogle(params);
|
|
18531
|
-
}
|
|
18532
|
-
return callOpenAiCompatible(params);
|
|
18533
|
-
}
|
|
18534
|
-
async function callAnthropic(params) {
|
|
18535
|
-
const res = await fetch("https://api.anthropic.com/v1/messages", {
|
|
18536
|
-
method: "POST",
|
|
18537
|
-
headers: {
|
|
18538
|
-
"x-api-key": params.apiKey,
|
|
18539
|
-
"content-type": "application/json",
|
|
18540
|
-
"anthropic-version": "2023-06-01"
|
|
18541
|
-
},
|
|
18542
|
-
body: JSON.stringify({
|
|
18543
|
-
model: params.model,
|
|
18544
|
-
max_tokens: MAX_TOKENS,
|
|
18545
|
-
system: SYSTEM_PROMPT,
|
|
18546
|
-
messages: [{ role: "user", content: params.userPrompt }]
|
|
18547
|
-
}),
|
|
18548
|
-
signal: AbortSignal.timeout(LLM_TIMEOUT_MS)
|
|
18549
|
-
});
|
|
18550
|
-
if (!res.ok) {
|
|
18551
|
-
throw new Error(`Anthropic API ${res.status}: ${await res.text().catch(() => "")}`);
|
|
18552
|
-
}
|
|
18553
|
-
const data = await res.json();
|
|
18554
|
-
return data.content?.[0]?.text?.trim() ?? "";
|
|
18555
|
-
}
|
|
18556
|
-
async function callOpenAiCompatible(params) {
|
|
18557
|
-
const baseUrl = resolveOpenAiBaseUrl(params.provider, params.baseUrl);
|
|
18558
|
-
const res = await fetch(`${baseUrl}/chat/completions`, {
|
|
18559
|
-
method: "POST",
|
|
18560
|
-
headers: {
|
|
18561
|
-
Authorization: `Bearer ${params.apiKey}`,
|
|
18562
|
-
"Content-Type": "application/json"
|
|
18563
|
-
},
|
|
18564
|
-
body: JSON.stringify({
|
|
18565
|
-
model: params.model,
|
|
18566
|
-
max_tokens: MAX_TOKENS,
|
|
18567
|
-
messages: [
|
|
18568
|
-
{ role: "system", content: SYSTEM_PROMPT },
|
|
18569
|
-
{ role: "user", content: params.userPrompt }
|
|
18570
|
-
]
|
|
18571
|
-
}),
|
|
18572
|
-
signal: AbortSignal.timeout(LLM_TIMEOUT_MS)
|
|
18573
|
-
});
|
|
18574
|
-
if (!res.ok) {
|
|
18575
|
-
throw new Error(`OpenAI-compatible API ${res.status}: ${await res.text().catch(() => "")}`);
|
|
18576
|
-
}
|
|
18577
|
-
const data = await res.json();
|
|
18578
|
-
return data.choices?.[0]?.message?.content?.trim() ?? "";
|
|
18579
|
-
}
|
|
18580
|
-
async function callGoogle(params) {
|
|
18581
|
-
const url = `https://generativelanguage.googleapis.com/v1beta/models/${params.model}:generateContent?key=${params.apiKey}`;
|
|
18582
|
-
const res = await fetch(url, {
|
|
18583
|
-
method: "POST",
|
|
18584
|
-
headers: { "Content-Type": "application/json" },
|
|
18585
|
-
body: JSON.stringify({
|
|
18586
|
-
system_instruction: { parts: [{ text: SYSTEM_PROMPT }] },
|
|
18587
|
-
contents: [{ parts: [{ text: params.userPrompt }] }],
|
|
18588
|
-
generationConfig: { maxOutputTokens: MAX_TOKENS }
|
|
18589
|
-
}),
|
|
18590
|
-
signal: AbortSignal.timeout(LLM_TIMEOUT_MS)
|
|
18591
|
-
});
|
|
18592
|
-
if (!res.ok) {
|
|
18593
|
-
throw new Error(`Google AI API ${res.status}: ${await res.text().catch(() => "")}`);
|
|
18594
|
-
}
|
|
18595
|
-
const data = await res.json();
|
|
18596
|
-
return data.candidates?.[0]?.content?.parts?.[0]?.text?.trim() ?? "";
|
|
18597
|
-
}
|
|
18598
|
-
function resolveOpenAiBaseUrl(provider, configuredBaseUrl) {
|
|
18599
|
-
if (configuredBaseUrl) return configuredBaseUrl.replace(/\/$/, "");
|
|
18600
|
-
const normalized = normalizeProvider(provider);
|
|
18601
|
-
const map = {
|
|
18602
|
-
openai: "https://api.openai.com/v1",
|
|
18603
|
-
openaicodex: "https://api.openai.com/v1",
|
|
18604
|
-
openrouter: "https://openrouter.ai/api/v1",
|
|
18605
|
-
groq: "https://api.groq.com/openai/v1",
|
|
18606
|
-
mistral: "https://api.mistral.ai/v1",
|
|
18607
|
-
deepseek: "https://api.deepseek.com/v1",
|
|
18608
|
-
xai: "https://api.x.ai/v1",
|
|
18609
|
-
together: "https://api.together.xyz/v1",
|
|
18610
|
-
venice: "https://api.venice.ai/api/v1",
|
|
18611
|
-
kilocode: "https://api.kilo.ai/api/gateway",
|
|
18612
|
-
litellm: "http://127.0.0.1:4000",
|
|
18613
|
-
moonshot: "https://api.moonshot.ai/v1",
|
|
18614
|
-
moonshotcn: "https://api.moonshot.cn/v1",
|
|
18615
|
-
minimax: "https://api.minimax.io/v1",
|
|
18616
|
-
minimaxcn: "https://api.minimaxi.com/v1",
|
|
18617
|
-
zai: "https://api.z.ai/v1",
|
|
18618
|
-
zaicn: "https://open.bigmodel.cn/api/paas/v4",
|
|
18619
|
-
qianfan: "https://qianfan.baidubce.com/v2",
|
|
18620
|
-
volcengine: "https://ark.cn-beijing.volces.com/api/v3",
|
|
18621
|
-
byteplus: "https://api.byteplus.com/v1",
|
|
18622
|
-
dashscope: "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
|
18623
|
-
xiaomi: "https://api.xiaomi.com/v1"
|
|
18624
|
-
};
|
|
18625
|
-
return map[normalized] ?? `https://api.${provider}.com/v1`;
|
|
18626
|
-
}
|
|
18627
|
-
var SYSTEM_PROMPT, LLM_TIMEOUT_MS, MAX_TOKENS;
|
|
18628
|
-
var init_llm_client = __esm({
|
|
18629
|
-
"src/llm-client.ts"() {
|
|
18630
|
-
"use strict";
|
|
18631
|
-
init_auth_resolver();
|
|
18632
|
-
SYSTEM_PROMPT = "You are a version control assistant for AI agent configuration files (personality, rules, memory, skills). Given the diffs, write a single-line commit message (max 72 chars). Describe WHAT changed semantically, not technically. No quotes, no conventional-commit prefix. Return ONLY the message.";
|
|
18633
|
-
LLM_TIMEOUT_MS = 15e3;
|
|
18634
|
-
MAX_TOKENS = 100;
|
|
18635
|
-
}
|
|
18636
|
-
});
|
|
18637
|
-
|
|
18638
18419
|
// ../core/dist/tracker.js
|
|
18639
18420
|
import fsPromises3 from "node:fs/promises";
|
|
18640
18421
|
import path4 from "node:path";
|
|
@@ -23892,8 +23673,95 @@ function createWatcherService(tracker, api) {
|
|
|
23892
23673
|
};
|
|
23893
23674
|
}
|
|
23894
23675
|
|
|
23676
|
+
// src/auth-resolver.ts
|
|
23677
|
+
import fsPromises5 from "node:fs/promises";
|
|
23678
|
+
import path6 from "node:path";
|
|
23679
|
+
import os2 from "node:os";
|
|
23680
|
+
function normalizeProvider(provider) {
|
|
23681
|
+
return provider.toLowerCase().replace(/-/g, "").replace(/_/g, "");
|
|
23682
|
+
}
|
|
23683
|
+
async function resolveApiKey(provider) {
|
|
23684
|
+
const profileKey = await readAuthProfileKey(provider);
|
|
23685
|
+
if (profileKey) return profileKey;
|
|
23686
|
+
return readEnvApiKey(provider);
|
|
23687
|
+
}
|
|
23688
|
+
async function readAuthProfileKey(provider) {
|
|
23689
|
+
const candidates = buildAuthProfilePaths();
|
|
23690
|
+
for (const filepath of candidates) {
|
|
23691
|
+
try {
|
|
23692
|
+
const content = await fsPromises5.readFile(filepath, "utf-8");
|
|
23693
|
+
const store = JSON.parse(content);
|
|
23694
|
+
if (!store.profiles || typeof store.profiles !== "object") continue;
|
|
23695
|
+
const normalized = normalizeProvider(provider);
|
|
23696
|
+
for (const credential of Object.values(store.profiles)) {
|
|
23697
|
+
if (normalizeProvider(credential.provider) !== normalized) continue;
|
|
23698
|
+
if (credential.type === "api_key" && credential.key) {
|
|
23699
|
+
return credential.key;
|
|
23700
|
+
}
|
|
23701
|
+
if (credential.type === "token" && credential.token) {
|
|
23702
|
+
return credential.token;
|
|
23703
|
+
}
|
|
23704
|
+
const ref = credential.keyRef ?? credential.tokenRef;
|
|
23705
|
+
if (ref?.source === "env" && ref.key) {
|
|
23706
|
+
const envVal = process.env[ref.key];
|
|
23707
|
+
if (envVal) return envVal;
|
|
23708
|
+
}
|
|
23709
|
+
}
|
|
23710
|
+
} catch {
|
|
23711
|
+
continue;
|
|
23712
|
+
}
|
|
23713
|
+
}
|
|
23714
|
+
return null;
|
|
23715
|
+
}
|
|
23716
|
+
function buildAuthProfilePaths() {
|
|
23717
|
+
const home = os2.homedir();
|
|
23718
|
+
const paths = [];
|
|
23719
|
+
const envHome = process.env.OPENCLAW_HOME;
|
|
23720
|
+
if (envHome) {
|
|
23721
|
+
paths.push(path6.join(envHome, "auth-profiles.json"));
|
|
23722
|
+
}
|
|
23723
|
+
paths.push(
|
|
23724
|
+
path6.join(home, ".openclaw", "auth-profiles.json"),
|
|
23725
|
+
path6.join(home, ".config", "openclaw", "auth-profiles.json")
|
|
23726
|
+
);
|
|
23727
|
+
return paths;
|
|
23728
|
+
}
|
|
23729
|
+
function readEnvApiKey(provider) {
|
|
23730
|
+
const normalized = normalizeProvider(provider);
|
|
23731
|
+
const map = {
|
|
23732
|
+
anthropic: ["ANTHROPIC_API_KEY"],
|
|
23733
|
+
openai: ["OPENAI_API_KEY"],
|
|
23734
|
+
openaicodex: ["OPENAI_API_KEY"],
|
|
23735
|
+
openrouter: ["OPENROUTER_API_KEY"],
|
|
23736
|
+
google: ["GEMINI_API_KEY", "GOOGLE_API_KEY", "GOOGLE_GENERATIVE_AI_API_KEY"],
|
|
23737
|
+
groq: ["GROQ_API_KEY"],
|
|
23738
|
+
mistral: ["MISTRAL_API_KEY"],
|
|
23739
|
+
deepseek: ["DEEPSEEK_API_KEY"],
|
|
23740
|
+
xai: ["XAI_API_KEY"],
|
|
23741
|
+
together: ["TOGETHER_API_KEY"],
|
|
23742
|
+
venice: ["VENICE_API_KEY"],
|
|
23743
|
+
moonshot: ["MOONSHOT_API_KEY"],
|
|
23744
|
+
moonshotcn: ["MOONSHOT_API_KEY"],
|
|
23745
|
+
minimax: ["MINIMAX_API_KEY"],
|
|
23746
|
+
minimaxcn: ["MINIMAX_API_KEY"],
|
|
23747
|
+
zai: ["ZAI_API_KEY", "Z_AI_API_KEY"],
|
|
23748
|
+
qianfan: ["QIANFAN_API_KEY"],
|
|
23749
|
+
volcengine: ["VOLCANO_ENGINE_API_KEY"],
|
|
23750
|
+
byteplus: ["BYTEPLUS_API_KEY"],
|
|
23751
|
+
dashscope: ["DASHSCOPE_API_KEY"],
|
|
23752
|
+
xiaomi: ["XIAOMI_API_KEY"],
|
|
23753
|
+
kilocode: ["KILOCODE_API_KEY"],
|
|
23754
|
+
litellm: ["LITELLM_API_KEY"]
|
|
23755
|
+
};
|
|
23756
|
+
const envKeys = map[normalized] ?? [`${provider.toUpperCase().replace(/-/g, "_")}_API_KEY`];
|
|
23757
|
+
for (const envKey of envKeys) {
|
|
23758
|
+
const val = process.env[envKey];
|
|
23759
|
+
if (val) return val;
|
|
23760
|
+
}
|
|
23761
|
+
return null;
|
|
23762
|
+
}
|
|
23763
|
+
|
|
23895
23764
|
// src/llm-provider.ts
|
|
23896
|
-
init_auth_resolver();
|
|
23897
23765
|
var MAX_DIFF_CHARS = 4e3;
|
|
23898
23766
|
async function createOpenClawLlmProvider(api) {
|
|
23899
23767
|
const modelSpec = resolveModelFromConfig(api.config);
|
|
@@ -23923,8 +23791,8 @@ async function createOpenClawLlmProvider(api) {
|
|
|
23923
23791
|
async generateCommitMessage(diffs) {
|
|
23924
23792
|
const diffText = diffs.map((d) => `--- ${d.file} ---
|
|
23925
23793
|
${d.unified}`).join("\n").slice(0, MAX_DIFF_CHARS);
|
|
23926
|
-
const { callLlm
|
|
23927
|
-
return
|
|
23794
|
+
const { callLlm } = await import("./llm-client.js");
|
|
23795
|
+
return callLlm({
|
|
23928
23796
|
provider: modelSpec.provider,
|
|
23929
23797
|
model: modelSpec.model,
|
|
23930
23798
|
apiKey,
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
// src/auth-resolver.ts
|
|
2
|
+
import fsPromises from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
function normalizeProvider(provider) {
|
|
6
|
+
return provider.toLowerCase().replace(/-/g, "").replace(/_/g, "");
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// src/llm-client.ts
|
|
10
|
+
var SYSTEM_PROMPT = "You are a version control assistant for AI agent configuration files (personality, rules, memory, skills). Given the diffs, write a single-line commit message (max 72 chars). Describe WHAT changed semantically, not technically. No quotes, no conventional-commit prefix. Return ONLY the message.";
|
|
11
|
+
var LLM_TIMEOUT_MS = 15e3;
|
|
12
|
+
var MAX_TOKENS = 100;
|
|
13
|
+
async function callLlm(params) {
|
|
14
|
+
const normalized = normalizeProvider(params.provider);
|
|
15
|
+
if (normalized === "anthropic") {
|
|
16
|
+
return callAnthropic(params);
|
|
17
|
+
}
|
|
18
|
+
if (normalized === "google") {
|
|
19
|
+
return callGoogle(params);
|
|
20
|
+
}
|
|
21
|
+
return callOpenAiCompatible(params);
|
|
22
|
+
}
|
|
23
|
+
async function callAnthropic(params) {
|
|
24
|
+
const res = await fetch("https://api.anthropic.com/v1/messages", {
|
|
25
|
+
method: "POST",
|
|
26
|
+
headers: {
|
|
27
|
+
"x-api-key": params.apiKey,
|
|
28
|
+
"content-type": "application/json",
|
|
29
|
+
"anthropic-version": "2023-06-01"
|
|
30
|
+
},
|
|
31
|
+
body: JSON.stringify({
|
|
32
|
+
model: params.model,
|
|
33
|
+
max_tokens: MAX_TOKENS,
|
|
34
|
+
system: SYSTEM_PROMPT,
|
|
35
|
+
messages: [{ role: "user", content: params.userPrompt }]
|
|
36
|
+
}),
|
|
37
|
+
signal: AbortSignal.timeout(LLM_TIMEOUT_MS)
|
|
38
|
+
});
|
|
39
|
+
if (!res.ok) {
|
|
40
|
+
throw new Error(`Anthropic API ${res.status}: ${await res.text().catch(() => "")}`);
|
|
41
|
+
}
|
|
42
|
+
const data = await res.json();
|
|
43
|
+
return data.content?.[0]?.text?.trim() ?? "";
|
|
44
|
+
}
|
|
45
|
+
async function callOpenAiCompatible(params) {
|
|
46
|
+
const baseUrl = resolveOpenAiBaseUrl(params.provider, params.baseUrl);
|
|
47
|
+
const res = await fetch(`${baseUrl}/chat/completions`, {
|
|
48
|
+
method: "POST",
|
|
49
|
+
headers: {
|
|
50
|
+
Authorization: `Bearer ${params.apiKey}`,
|
|
51
|
+
"Content-Type": "application/json"
|
|
52
|
+
},
|
|
53
|
+
body: JSON.stringify({
|
|
54
|
+
model: params.model,
|
|
55
|
+
max_tokens: MAX_TOKENS,
|
|
56
|
+
messages: [
|
|
57
|
+
{ role: "system", content: SYSTEM_PROMPT },
|
|
58
|
+
{ role: "user", content: params.userPrompt }
|
|
59
|
+
]
|
|
60
|
+
}),
|
|
61
|
+
signal: AbortSignal.timeout(LLM_TIMEOUT_MS)
|
|
62
|
+
});
|
|
63
|
+
if (!res.ok) {
|
|
64
|
+
throw new Error(`OpenAI-compatible API ${res.status}: ${await res.text().catch(() => "")}`);
|
|
65
|
+
}
|
|
66
|
+
const data = await res.json();
|
|
67
|
+
return data.choices?.[0]?.message?.content?.trim() ?? "";
|
|
68
|
+
}
|
|
69
|
+
async function callGoogle(params) {
|
|
70
|
+
const url = `https://generativelanguage.googleapis.com/v1beta/models/${params.model}:generateContent?key=${params.apiKey}`;
|
|
71
|
+
const res = await fetch(url, {
|
|
72
|
+
method: "POST",
|
|
73
|
+
headers: { "Content-Type": "application/json" },
|
|
74
|
+
body: JSON.stringify({
|
|
75
|
+
system_instruction: { parts: [{ text: SYSTEM_PROMPT }] },
|
|
76
|
+
contents: [{ parts: [{ text: params.userPrompt }] }],
|
|
77
|
+
generationConfig: { maxOutputTokens: MAX_TOKENS }
|
|
78
|
+
}),
|
|
79
|
+
signal: AbortSignal.timeout(LLM_TIMEOUT_MS)
|
|
80
|
+
});
|
|
81
|
+
if (!res.ok) {
|
|
82
|
+
throw new Error(`Google AI API ${res.status}: ${await res.text().catch(() => "")}`);
|
|
83
|
+
}
|
|
84
|
+
const data = await res.json();
|
|
85
|
+
return data.candidates?.[0]?.content?.parts?.[0]?.text?.trim() ?? "";
|
|
86
|
+
}
|
|
87
|
+
function resolveOpenAiBaseUrl(provider, configuredBaseUrl) {
|
|
88
|
+
if (configuredBaseUrl) return configuredBaseUrl.replace(/\/$/, "");
|
|
89
|
+
const normalized = normalizeProvider(provider);
|
|
90
|
+
const map = {
|
|
91
|
+
openai: "https://api.openai.com/v1",
|
|
92
|
+
openaicodex: "https://api.openai.com/v1",
|
|
93
|
+
openrouter: "https://openrouter.ai/api/v1",
|
|
94
|
+
groq: "https://api.groq.com/openai/v1",
|
|
95
|
+
mistral: "https://api.mistral.ai/v1",
|
|
96
|
+
deepseek: "https://api.deepseek.com/v1",
|
|
97
|
+
xai: "https://api.x.ai/v1",
|
|
98
|
+
together: "https://api.together.xyz/v1",
|
|
99
|
+
venice: "https://api.venice.ai/api/v1",
|
|
100
|
+
kilocode: "https://api.kilo.ai/api/gateway",
|
|
101
|
+
litellm: "http://127.0.0.1:4000",
|
|
102
|
+
moonshot: "https://api.moonshot.ai/v1",
|
|
103
|
+
moonshotcn: "https://api.moonshot.cn/v1",
|
|
104
|
+
minimax: "https://api.minimax.io/v1",
|
|
105
|
+
minimaxcn: "https://api.minimaxi.com/v1",
|
|
106
|
+
zai: "https://api.z.ai/v1",
|
|
107
|
+
zaicn: "https://open.bigmodel.cn/api/paas/v4",
|
|
108
|
+
qianfan: "https://qianfan.baidubce.com/v2",
|
|
109
|
+
volcengine: "https://ark.cn-beijing.volces.com/api/v3",
|
|
110
|
+
byteplus: "https://api.byteplus.com/v1",
|
|
111
|
+
dashscope: "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
|
112
|
+
xiaomi: "https://api.xiaomi.com/v1"
|
|
113
|
+
};
|
|
114
|
+
return map[normalized] ?? `https://api.${provider}.com/v1`;
|
|
115
|
+
}
|
|
116
|
+
export {
|
|
117
|
+
callLlm
|
|
118
|
+
};
|
package/package.json
CHANGED
|
@@ -2,10 +2,6 @@
|
|
|
2
2
|
name: mindkeeper
|
|
3
3
|
description: Version control for agent context files — view history, compare versions, and rollback changes
|
|
4
4
|
version: 1.0.0
|
|
5
|
-
metadata:
|
|
6
|
-
openclaw:
|
|
7
|
-
requires:
|
|
8
|
-
config: ["workspace.dir"]
|
|
9
5
|
---
|
|
10
6
|
|
|
11
7
|
# Mindkeeper — Version Control for Agent Context
|