@p-sw/brainbox 0.1.2-alpha.4 → 0.1.2-alpha.6
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 +124 -68
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -295,7 +295,7 @@ function removeProviderAuth(provider) {
|
|
|
295
295
|
// src/config/index.ts
|
|
296
296
|
var config = {
|
|
297
297
|
get debug() {
|
|
298
|
-
return readRootFile().debug;
|
|
298
|
+
return process.env.DEBUG_MODE ? process.env.DEBUG_MODE.toLowerCase() === "true" : readRootFile().debug;
|
|
299
299
|
},
|
|
300
300
|
brainboxRoot,
|
|
301
301
|
get supermemoryApiKey() {
|
|
@@ -430,6 +430,21 @@ function defaultReasoningEffort(effort, model, identityModel) {
|
|
|
430
430
|
return effort;
|
|
431
431
|
return model === identityModel ? "medium" : "none";
|
|
432
432
|
}
|
|
433
|
+
function stripThinkTags(content) {
|
|
434
|
+
return content.replace(/<think\b[^>]*>[\s\S]*?<\/think>/gi, "").trim();
|
|
435
|
+
}
|
|
436
|
+
function parseModelJson(content) {
|
|
437
|
+
const cleaned = stripThinkTags(content);
|
|
438
|
+
try {
|
|
439
|
+
return JSON.parse(cleaned);
|
|
440
|
+
} catch (first) {
|
|
441
|
+
const fence = cleaned.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
|
442
|
+
if (fence?.[1]) {
|
|
443
|
+
return JSON.parse(fence[1].trim());
|
|
444
|
+
}
|
|
445
|
+
throw first;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
433
448
|
function readAuthString(auth, key, envName) {
|
|
434
449
|
const fromAuth = typeof auth?.[key] === "string" ? auth[key] : undefined;
|
|
435
450
|
if (fromAuth)
|
|
@@ -546,7 +561,7 @@ function fromOrChoice(choice) {
|
|
|
546
561
|
}));
|
|
547
562
|
return {
|
|
548
563
|
message: {
|
|
549
|
-
content: typeof msg.content === "string" ? msg.content : undefined,
|
|
564
|
+
content: typeof msg.content === "string" ? stripThinkTags(msg.content) : undefined,
|
|
550
565
|
toolCalls
|
|
551
566
|
}
|
|
552
567
|
};
|
|
@@ -598,13 +613,14 @@ class OpenRouterExecutor extends LLMExecutor {
|
|
|
598
613
|
stream: false
|
|
599
614
|
}
|
|
600
615
|
});
|
|
601
|
-
const
|
|
616
|
+
const raw = result.choices[0]?.message?.content;
|
|
617
|
+
const content = typeof raw === "string" ? stripThinkTags(raw) : raw;
|
|
602
618
|
if (!content) {
|
|
603
619
|
log3.debug(`call: empty content in choice 0`);
|
|
604
620
|
throw new Error("Empty response from model");
|
|
605
621
|
}
|
|
606
622
|
log3.debug(`call: response ${content.length} chars`);
|
|
607
|
-
return jsonMode ?
|
|
623
|
+
return jsonMode ? parseModelJson(content) : content;
|
|
608
624
|
}
|
|
609
625
|
async chatWithTools(model, options) {
|
|
610
626
|
log3.debug(`chatWithTools: model=${model} msgs=${options.messages.length} tools=${options.tools.length}`);
|
|
@@ -663,7 +679,7 @@ function fromChoice(choice) {
|
|
|
663
679
|
}));
|
|
664
680
|
return {
|
|
665
681
|
message: {
|
|
666
|
-
content: typeof msg.content === "string" ? msg.content : undefined,
|
|
682
|
+
content: typeof msg.content === "string" ? stripThinkTags(msg.content) : undefined,
|
|
667
683
|
toolCalls
|
|
668
684
|
}
|
|
669
685
|
};
|
|
@@ -778,13 +794,14 @@ class OpenAICompatibleExecutor extends LLMExecutor {
|
|
|
778
794
|
reasoningEffort: reasoning
|
|
779
795
|
});
|
|
780
796
|
const data = await this.sendRequest(body, options.reasoningEffort);
|
|
781
|
-
const
|
|
797
|
+
const raw = data.choices?.[0]?.message?.content;
|
|
798
|
+
const content = typeof raw === "string" ? stripThinkTags(raw) : raw;
|
|
782
799
|
if (!content) {
|
|
783
800
|
log4.debug(`call: empty content in choice 0`);
|
|
784
801
|
throw new Error("Empty response from model");
|
|
785
802
|
}
|
|
786
803
|
log4.debug(`call: response ${content.length} chars`);
|
|
787
|
-
return jsonMode ?
|
|
804
|
+
return jsonMode ? parseModelJson(content) : content;
|
|
788
805
|
}
|
|
789
806
|
async chatWithTools(model, options) {
|
|
790
807
|
const reasoning = defaultReasoningEffort(options.reasoningEffort, model, this.models.identity);
|
|
@@ -1099,28 +1116,34 @@ class ZenMuxExecutor extends OpenAICompatibleExecutor {
|
|
|
1099
1116
|
}
|
|
1100
1117
|
|
|
1101
1118
|
// src/provider/providers/minimax.ts
|
|
1102
|
-
class
|
|
1119
|
+
class MiniMaxBase extends OpenAICompatibleExecutor {
|
|
1120
|
+
buildBody(opts) {
|
|
1121
|
+
const body = super.buildBody(opts);
|
|
1122
|
+
delete body["reasoning_effort"];
|
|
1123
|
+
body["reasoning_split"] = true;
|
|
1124
|
+
body["thinking"] = opts.reasoningEffort && opts.reasoningEffort !== "none" ? { type: "adaptive" } : { type: "disabled" };
|
|
1125
|
+
return body;
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
function minimaxOpts(providerName, baseURL, opts) {
|
|
1129
|
+
return {
|
|
1130
|
+
providerName,
|
|
1131
|
+
baseURL,
|
|
1132
|
+
apiKey: opts.apiKey,
|
|
1133
|
+
conversationModel: opts.conversationModel,
|
|
1134
|
+
identityModel: opts.identityModel
|
|
1135
|
+
};
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
class MiniMaxExecutor extends MiniMaxBase {
|
|
1103
1139
|
constructor(opts) {
|
|
1104
|
-
super(
|
|
1105
|
-
providerName: "minimax",
|
|
1106
|
-
baseURL: "https://api.minimax.io/v1",
|
|
1107
|
-
apiKey: opts.apiKey,
|
|
1108
|
-
conversationModel: opts.conversationModel,
|
|
1109
|
-
identityModel: opts.identityModel
|
|
1110
|
-
});
|
|
1140
|
+
super(minimaxOpts("minimax", "https://api.minimax.io/v1", opts));
|
|
1111
1141
|
}
|
|
1112
1142
|
}
|
|
1113
1143
|
|
|
1114
|
-
|
|
1115
|
-
class MiniMaxCnExecutor extends OpenAICompatibleExecutor {
|
|
1144
|
+
class MiniMaxCnExecutor extends MiniMaxBase {
|
|
1116
1145
|
constructor(opts) {
|
|
1117
|
-
super(
|
|
1118
|
-
providerName: "minimax-cn",
|
|
1119
|
-
baseURL: "https://api.minimaxi.com/v1",
|
|
1120
|
-
apiKey: opts.apiKey,
|
|
1121
|
-
conversationModel: opts.conversationModel,
|
|
1122
|
-
identityModel: opts.identityModel
|
|
1123
|
-
});
|
|
1146
|
+
super(minimaxOpts("minimax-cn", "https://api.minimaxi.com/v1", opts));
|
|
1124
1147
|
}
|
|
1125
1148
|
}
|
|
1126
1149
|
|
|
@@ -1273,7 +1296,17 @@ class CloudflareGatewayExecutor extends OpenAICompatibleExecutor {
|
|
|
1273
1296
|
// src/provider/providers/cloudflare_workers.ts
|
|
1274
1297
|
function toCloudflareMessage(m) {
|
|
1275
1298
|
if (m.role === "assistant") {
|
|
1276
|
-
return {
|
|
1299
|
+
return {
|
|
1300
|
+
role: "assistant",
|
|
1301
|
+
content: m.content ?? "",
|
|
1302
|
+
tool_calls: m.toolCalls?.map((c) => {
|
|
1303
|
+
let args = c.function.arguments;
|
|
1304
|
+
try {
|
|
1305
|
+
args = JSON.parse(c.function.arguments);
|
|
1306
|
+
} catch {}
|
|
1307
|
+
return { id: c.id, name: c.function.name, arguments: args };
|
|
1308
|
+
})
|
|
1309
|
+
};
|
|
1277
1310
|
}
|
|
1278
1311
|
if (m.role === "tool") {
|
|
1279
1312
|
return { role: "tool", content: m.content, tool_call_id: m.toolCallId };
|
|
@@ -1335,11 +1368,11 @@ class CloudflareWorkersExecutor extends LLMExecutor {
|
|
|
1335
1368
|
if (data.errors && data.errors.length > 0) {
|
|
1336
1369
|
throw new Error(`cloudflare-workers API error: ${data.errors.map((e) => e.message).join("; ")}`);
|
|
1337
1370
|
}
|
|
1338
|
-
const content = data.result?.response ?? "";
|
|
1371
|
+
const content = stripThinkTags(data.result?.response ?? "");
|
|
1339
1372
|
if (!content) {
|
|
1340
1373
|
throw new Error("Empty response from model");
|
|
1341
1374
|
}
|
|
1342
|
-
return jsonMode ?
|
|
1375
|
+
return jsonMode ? parseModelJson(content) : content;
|
|
1343
1376
|
}
|
|
1344
1377
|
async chatWithTools(model, options) {
|
|
1345
1378
|
const reasoning = defaultReasoningEffort(options.reasoningEffort, model, this.models.identity);
|
|
@@ -1364,7 +1397,7 @@ class CloudflareWorkersExecutor extends LLMExecutor {
|
|
|
1364
1397
|
if (data.errors && data.errors.length > 0) {
|
|
1365
1398
|
throw new Error(`cloudflare-workers API error: ${data.errors.map((e) => e.message).join("; ")}`);
|
|
1366
1399
|
}
|
|
1367
|
-
const content = data.result?.response ?? "";
|
|
1400
|
+
const content = stripThinkTags(data.result?.response ?? "");
|
|
1368
1401
|
const toolCalls = data.result?.tool_calls?.map((c, idx) => ({
|
|
1369
1402
|
id: `call_${idx}`,
|
|
1370
1403
|
function: {
|
|
@@ -1402,7 +1435,8 @@ class AzureOpenAIExecutor extends OpenAICompatibleExecutor {
|
|
|
1402
1435
|
super({
|
|
1403
1436
|
providerName: "azure-openai",
|
|
1404
1437
|
baseURL: `https://${resource || "__resource__"}.openai.azure.com/openai/deployments`,
|
|
1405
|
-
apiKey:
|
|
1438
|
+
apiKey: "",
|
|
1439
|
+
defaultHeaders: { "api-key": opts.apiKey },
|
|
1406
1440
|
conversationModel: opts.conversationModel,
|
|
1407
1441
|
identityModel: opts.identityModel
|
|
1408
1442
|
});
|
|
@@ -1422,7 +1456,8 @@ class AzureCognitiveExecutor extends OpenAICompatibleExecutor {
|
|
|
1422
1456
|
super({
|
|
1423
1457
|
providerName: "azure-cognitive",
|
|
1424
1458
|
baseURL: `https://${resource || "__resource__"}.cognitiveservices.azure.com/openai/deployments`,
|
|
1425
|
-
apiKey:
|
|
1459
|
+
apiKey: "",
|
|
1460
|
+
defaultHeaders: { "api-key": opts.apiKey },
|
|
1426
1461
|
conversationModel: opts.conversationModel,
|
|
1427
1462
|
identityModel: opts.identityModel
|
|
1428
1463
|
});
|
|
@@ -1546,44 +1581,50 @@ class AnthropicExecutor extends LLMExecutor {
|
|
|
1546
1581
|
const reasoning = defaultReasoningEffort(options.reasoningEffort, model, this.models.identity);
|
|
1547
1582
|
const log5 = logger.child("llm:anthropic");
|
|
1548
1583
|
log5.debug(`call: model=${model} jsonSchema=${jsonMode ? options.jsonSchemaName : "-"} msgLen=${options.message.length}`);
|
|
1584
|
+
const outputCap = 4096;
|
|
1549
1585
|
const body = {
|
|
1550
1586
|
model,
|
|
1551
|
-
max_tokens:
|
|
1587
|
+
max_tokens: outputCap,
|
|
1552
1588
|
system: options.instruction,
|
|
1553
1589
|
messages: [{ role: "user", content: options.message }]
|
|
1554
1590
|
};
|
|
1555
1591
|
if (reasoning !== "none") {
|
|
1592
|
+
const budget = REASONING_BUDGET[reasoning];
|
|
1593
|
+
body["max_tokens"] = budget + outputCap;
|
|
1556
1594
|
body["thinking"] = {
|
|
1557
1595
|
type: "enabled",
|
|
1558
|
-
budget_tokens:
|
|
1596
|
+
budget_tokens: budget
|
|
1559
1597
|
};
|
|
1560
1598
|
}
|
|
1561
1599
|
const data = await this.send(body);
|
|
1562
1600
|
if (data.error) {
|
|
1563
1601
|
throw new Error(`anthropic API error: ${data.error.message ?? "unknown"}`);
|
|
1564
1602
|
}
|
|
1565
|
-
const text = (data.content ?? []).filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
1603
|
+
const text = stripThinkTags((data.content ?? []).filter((b) => b.type === "text").map((b) => b.text).join(""));
|
|
1566
1604
|
if (!text) {
|
|
1567
1605
|
throw new Error("Empty response from model");
|
|
1568
1606
|
}
|
|
1569
|
-
return jsonMode ?
|
|
1607
|
+
return jsonMode ? parseModelJson(text) : text;
|
|
1570
1608
|
}
|
|
1571
1609
|
async chatWithTools(model, options) {
|
|
1572
1610
|
const reasoning = defaultReasoningEffort(options.reasoningEffort, model, this.models.identity);
|
|
1573
1611
|
const log5 = logger.child("llm:anthropic");
|
|
1574
1612
|
log5.debug(`chatWithTools: model=${model} msgs=${options.messages.length} tools=${options.tools.length}`);
|
|
1575
1613
|
const { system, msgs } = toAnthropicMessages(options.messages);
|
|
1614
|
+
const outputCap = 4096;
|
|
1576
1615
|
const body = {
|
|
1577
1616
|
model,
|
|
1578
|
-
max_tokens:
|
|
1617
|
+
max_tokens: outputCap,
|
|
1579
1618
|
system: system ?? options.instruction,
|
|
1580
1619
|
messages: msgs,
|
|
1581
1620
|
tools: options.tools.map(toAnthropicTool)
|
|
1582
1621
|
};
|
|
1583
1622
|
if (reasoning !== "none") {
|
|
1623
|
+
const budget = REASONING_BUDGET[reasoning];
|
|
1624
|
+
body["max_tokens"] = budget + outputCap;
|
|
1584
1625
|
body["thinking"] = {
|
|
1585
1626
|
type: "enabled",
|
|
1586
|
-
budget_tokens:
|
|
1627
|
+
budget_tokens: budget
|
|
1587
1628
|
};
|
|
1588
1629
|
}
|
|
1589
1630
|
const data = await this.send(body);
|
|
@@ -1591,7 +1632,7 @@ class AnthropicExecutor extends LLMExecutor {
|
|
|
1591
1632
|
throw new Error(`anthropic API error: ${data.error.message ?? "unknown"}`);
|
|
1592
1633
|
}
|
|
1593
1634
|
const blocks = data.content ?? [];
|
|
1594
|
-
const text = blocks.filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
1635
|
+
const text = stripThinkTags(blocks.filter((b) => b.type === "text").map((b) => b.text).join(""));
|
|
1595
1636
|
const toolCalls = blocks.filter((b) => b.type === "tool_use").map((b) => ({
|
|
1596
1637
|
id: b.id,
|
|
1597
1638
|
function: {
|
|
@@ -1717,7 +1758,7 @@ function toAnthropicTool2(t) {
|
|
|
1717
1758
|
}
|
|
1718
1759
|
function extractAnthropicContent(data) {
|
|
1719
1760
|
const content = data["content"] ?? [];
|
|
1720
|
-
const text = content.filter((b) => b["type"] === "text").map((b) => b["text"]).join("");
|
|
1761
|
+
const text = stripThinkTags(content.filter((b) => b["type"] === "text").map((b) => b["text"]).join(""));
|
|
1721
1762
|
const toolCalls = content.filter((b) => b["type"] === "tool_use").map((b) => ({
|
|
1722
1763
|
id: b["id"],
|
|
1723
1764
|
function: {
|
|
@@ -1792,7 +1833,7 @@ class BedrockExecutor extends LLMExecutor {
|
|
|
1792
1833
|
if (!text) {
|
|
1793
1834
|
throw new Error("Empty response from model");
|
|
1794
1835
|
}
|
|
1795
|
-
return jsonMode ?
|
|
1836
|
+
return jsonMode ? parseModelJson(text) : text;
|
|
1796
1837
|
}
|
|
1797
1838
|
async chatWithTools(model, options) {
|
|
1798
1839
|
const log5 = logger.child("llm:bedrock");
|
|
@@ -1822,6 +1863,7 @@ var VertexAuthSchema = z5.object({
|
|
|
1822
1863
|
}).loose();
|
|
1823
1864
|
function toGeminiContents(messages) {
|
|
1824
1865
|
const out = [];
|
|
1866
|
+
const nameByCallId = new Map;
|
|
1825
1867
|
for (const m of messages) {
|
|
1826
1868
|
if (m.role === "system")
|
|
1827
1869
|
continue;
|
|
@@ -1835,6 +1877,7 @@ function toGeminiContents(messages) {
|
|
|
1835
1877
|
parts.push({ text: m.content });
|
|
1836
1878
|
if (m.toolCalls) {
|
|
1837
1879
|
for (const c of m.toolCalls) {
|
|
1880
|
+
nameByCallId.set(c.id, c.function.name);
|
|
1838
1881
|
let args = {};
|
|
1839
1882
|
try {
|
|
1840
1883
|
args = c.function.arguments ? JSON.parse(c.function.arguments) : {};
|
|
@@ -1856,21 +1899,26 @@ function toGeminiContents(messages) {
|
|
|
1856
1899
|
}
|
|
1857
1900
|
out.push({
|
|
1858
1901
|
role: "user",
|
|
1859
|
-
parts: [
|
|
1902
|
+
parts: [
|
|
1903
|
+
{
|
|
1904
|
+
functionResponse: {
|
|
1905
|
+
name: nameByCallId.get(m.toolCallId) ?? "",
|
|
1906
|
+
response
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
]
|
|
1860
1910
|
});
|
|
1861
1911
|
}
|
|
1862
1912
|
}
|
|
1863
1913
|
return out;
|
|
1864
1914
|
}
|
|
1865
|
-
function
|
|
1915
|
+
function toGeminiTools(tools) {
|
|
1866
1916
|
return {
|
|
1867
|
-
functionDeclarations:
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
}
|
|
1873
|
-
]
|
|
1917
|
+
functionDeclarations: tools.map((t) => ({
|
|
1918
|
+
name: t.name,
|
|
1919
|
+
description: t.description,
|
|
1920
|
+
parameters: t.parameters ?? { type: "object", properties: {} }
|
|
1921
|
+
}))
|
|
1874
1922
|
};
|
|
1875
1923
|
}
|
|
1876
1924
|
function extractFromGemini(data) {
|
|
@@ -1891,7 +1939,10 @@ function extractFromGemini(data) {
|
|
|
1891
1939
|
});
|
|
1892
1940
|
}
|
|
1893
1941
|
}
|
|
1894
|
-
return {
|
|
1942
|
+
return {
|
|
1943
|
+
text: stripThinkTags(text),
|
|
1944
|
+
toolCalls: toolCalls.length > 0 ? toolCalls : undefined
|
|
1945
|
+
};
|
|
1895
1946
|
}
|
|
1896
1947
|
|
|
1897
1948
|
class VertexExecutor extends LLMExecutor {
|
|
@@ -1957,7 +2008,7 @@ class VertexExecutor extends LLMExecutor {
|
|
|
1957
2008
|
if (!text) {
|
|
1958
2009
|
throw new Error("Empty response from model");
|
|
1959
2010
|
}
|
|
1960
|
-
return jsonMode ?
|
|
2011
|
+
return jsonMode ? parseModelJson(text) : text;
|
|
1961
2012
|
}
|
|
1962
2013
|
async chatWithTools(model, options) {
|
|
1963
2014
|
const log5 = logger.child("llm:vertex");
|
|
@@ -1966,7 +2017,7 @@ class VertexExecutor extends LLMExecutor {
|
|
|
1966
2017
|
const body = {
|
|
1967
2018
|
contents,
|
|
1968
2019
|
systemInstruction: { parts: [{ text: options.instruction }] },
|
|
1969
|
-
tools: options.tools.length > 0 ? [
|
|
2020
|
+
tools: options.tools.length > 0 ? [toGeminiTools(options.tools)] : undefined
|
|
1970
2021
|
};
|
|
1971
2022
|
const data = await this.generate(model, body);
|
|
1972
2023
|
if (data.error) {
|
|
@@ -2074,11 +2125,11 @@ class GitLabDuoExecutor extends LLMExecutor {
|
|
|
2074
2125
|
if (data.error) {
|
|
2075
2126
|
throw new Error(`gitlab-duo API error: ${data.error.message ?? "unknown"}`);
|
|
2076
2127
|
}
|
|
2077
|
-
const content = data.choices?.[0]?.message?.content ?? "";
|
|
2128
|
+
const content = stripThinkTags(data.choices?.[0]?.message?.content ?? "");
|
|
2078
2129
|
if (!content) {
|
|
2079
2130
|
throw new Error("Empty response from model");
|
|
2080
2131
|
}
|
|
2081
|
-
return jsonMode ?
|
|
2132
|
+
return jsonMode ? parseModelJson(content) : content;
|
|
2082
2133
|
}
|
|
2083
2134
|
async chatWithTools(model, options) {
|
|
2084
2135
|
const log5 = logger.child("llm:gitlab-duo");
|
|
@@ -2102,7 +2153,7 @@ class GitLabDuoExecutor extends LLMExecutor {
|
|
|
2102
2153
|
}));
|
|
2103
2154
|
return {
|
|
2104
2155
|
message: {
|
|
2105
|
-
content: choice?.message?.content
|
|
2156
|
+
content: choice?.message?.content ? stripThinkTags(choice.message.content) : undefined,
|
|
2106
2157
|
toolCalls
|
|
2107
2158
|
}
|
|
2108
2159
|
};
|
|
@@ -2193,11 +2244,11 @@ class SnowflakeCortexExecutor extends LLMExecutor {
|
|
|
2193
2244
|
if (data.error) {
|
|
2194
2245
|
throw new Error(`snowflake-cortex API error: ${data.error.message ?? "unknown"}`);
|
|
2195
2246
|
}
|
|
2196
|
-
const content = data.choices?.[0]?.message?.content ?? data.message ?? "";
|
|
2247
|
+
const content = stripThinkTags(data.choices?.[0]?.message?.content ?? data.message ?? "");
|
|
2197
2248
|
if (!content) {
|
|
2198
2249
|
throw new Error("Empty response from model");
|
|
2199
2250
|
}
|
|
2200
|
-
return jsonMode ?
|
|
2251
|
+
return jsonMode ? parseModelJson(content) : content;
|
|
2201
2252
|
}
|
|
2202
2253
|
async chatWithTools(model, options) {
|
|
2203
2254
|
const log5 = logger.child("llm:snowflake-cortex");
|
|
@@ -2215,7 +2266,7 @@ class SnowflakeCortexExecutor extends LLMExecutor {
|
|
|
2215
2266
|
throw new Error(`snowflake-cortex API error: ${data.error.message ?? "unknown"}`);
|
|
2216
2267
|
}
|
|
2217
2268
|
const choice = data.choices?.[0];
|
|
2218
|
-
const content = choice?.message?.content ?? data.message ?? "";
|
|
2269
|
+
const content = stripThinkTags(choice?.message?.content ?? data.message ?? "");
|
|
2219
2270
|
const toolCalls = choice?.message?.tool_calls?.map((c) => ({
|
|
2220
2271
|
id: c.id,
|
|
2221
2272
|
function: {
|
|
@@ -2516,13 +2567,13 @@ class Brain {
|
|
|
2516
2567
|
db;
|
|
2517
2568
|
space;
|
|
2518
2569
|
brainbase;
|
|
2519
|
-
memory;
|
|
2520
2570
|
availabilityCache = new Map;
|
|
2521
|
-
|
|
2571
|
+
memory;
|
|
2572
|
+
constructor(db, space, brainbase, memory) {
|
|
2522
2573
|
this.db = db;
|
|
2523
2574
|
this.space = space;
|
|
2524
2575
|
this.brainbase = brainbase;
|
|
2525
|
-
this.memory = memory;
|
|
2576
|
+
this.memory = memory ?? new Memory(this.db, this.space);
|
|
2526
2577
|
log7.debug(`Brain constructed: id=${brainbase.brainId} name=${brainbase.displayName} space=${space.name}`);
|
|
2527
2578
|
}
|
|
2528
2579
|
async createDailySchedule(datetime) {
|
|
@@ -4291,6 +4342,9 @@ function RawInput({
|
|
|
4291
4342
|
onSubmit
|
|
4292
4343
|
}) {
|
|
4293
4344
|
const [value, setValue] = useState(initialValue);
|
|
4345
|
+
useEffect(() => {
|
|
4346
|
+
setValue(initialValue);
|
|
4347
|
+
}, [prompt, initialValue]);
|
|
4294
4348
|
useInput((input, key) => {
|
|
4295
4349
|
if (key.return) {
|
|
4296
4350
|
onSubmit(value);
|
|
@@ -5148,7 +5202,7 @@ function ModelApp2({
|
|
|
5148
5202
|
/* @__PURE__ */ jsxDEV5(Text5, {
|
|
5149
5203
|
dimColor: true,
|
|
5150
5204
|
children: [
|
|
5151
|
-
"
|
|
5205
|
+
"model name, or ",
|
|
5152
5206
|
/* @__PURE__ */ jsxDEV5(Text5, {
|
|
5153
5207
|
color: "cyan",
|
|
5154
5208
|
children: [
|
|
@@ -5156,7 +5210,7 @@ function ModelApp2({
|
|
|
5156
5210
|
"/"
|
|
5157
5211
|
]
|
|
5158
5212
|
}, undefined, true, undefined, this),
|
|
5159
|
-
"model
|
|
5213
|
+
"model — fine-tune later with ",
|
|
5160
5214
|
/* @__PURE__ */ jsxDEV5(Text5, {
|
|
5161
5215
|
color: "cyan",
|
|
5162
5216
|
children: "brainbox model"
|
|
@@ -5171,13 +5225,15 @@ function ModelApp2({
|
|
|
5171
5225
|
setError("Model cannot be empty");
|
|
5172
5226
|
return;
|
|
5173
5227
|
}
|
|
5174
|
-
|
|
5175
|
-
|
|
5228
|
+
const prefix = `${provider}/`;
|
|
5229
|
+
const full = value.startsWith(prefix) ? value : `${prefix}${value}`;
|
|
5230
|
+
if (full === prefix) {
|
|
5231
|
+
setError("Model cannot be empty");
|
|
5176
5232
|
return;
|
|
5177
5233
|
}
|
|
5178
|
-
setModelSlot("identity",
|
|
5179
|
-
setModelSlot("conversation",
|
|
5180
|
-
onDone(
|
|
5234
|
+
setModelSlot("identity", full);
|
|
5235
|
+
setModelSlot("conversation", full);
|
|
5236
|
+
onDone(full);
|
|
5181
5237
|
}
|
|
5182
5238
|
}, undefined, false, undefined, this),
|
|
5183
5239
|
error && /* @__PURE__ */ jsxDEV5(Text5, {
|
|
@@ -5282,7 +5338,7 @@ function BrainApp({
|
|
|
5282
5338
|
}, undefined, false, undefined, this),
|
|
5283
5339
|
busy ? /* @__PURE__ */ jsxDEV5(Text5, {
|
|
5284
5340
|
dimColor: true,
|
|
5285
|
-
children: "Creating brain…"
|
|
5341
|
+
children: "Creating brain… (This can take few minutes depending on the model's response speed)"
|
|
5286
5342
|
}, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV5(TextInput, {
|
|
5287
5343
|
prompt: "seed> ",
|
|
5288
5344
|
onSubmit: (raw) => {
|