@markus-global/cli 0.4.23 → 0.4.24
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/commands/auth.js +1 -1
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/doctor.js +1 -1
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +6 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/model.js +3 -3
- package/dist/commands/model.js.map +1 -1
- package/dist/commands/start.js +19 -4
- package/dist/commands/start.js.map +1 -1
- package/dist/markus.mjs +352 -179
- package/dist/web-ui/assets/{index-FxtMolbG.js → index-CJqOXq2-.js} +42 -42
- package/dist/web-ui/assets/index-vdyam0yR.css +1 -0
- package/dist/web-ui/index.html +2 -2
- package/package.json +1 -1
- package/dist/web-ui/assets/index-jBDtl4o2.css +0 -1
package/dist/markus.mjs
CHANGED
|
@@ -4061,8 +4061,9 @@ var init_models = __esm({
|
|
|
4061
4061
|
id: "deepseek",
|
|
4062
4062
|
label: "DeepSeek",
|
|
4063
4063
|
envKey: "DEEPSEEK_API_KEY",
|
|
4064
|
-
|
|
4065
|
-
|
|
4064
|
+
baseUrl: "https://api.deepseek.com",
|
|
4065
|
+
defaultModel: "deepseek-v4-flash",
|
|
4066
|
+
models: ["deepseek-v4-flash", "deepseek-v4-pro", "deepseek-chat", "deepseek-reasoner"]
|
|
4066
4067
|
}
|
|
4067
4068
|
];
|
|
4068
4069
|
}
|
|
@@ -8324,8 +8325,16 @@ var init_tool_selector = __esm({
|
|
|
8324
8325
|
result.push({ name: tool.name, description: tool.description, inputSchema: tool.inputSchema });
|
|
8325
8326
|
}
|
|
8326
8327
|
}
|
|
8328
|
+
const seen = new Set(result.map((t) => t.name));
|
|
8327
8329
|
result.push(this.buildDiscoverTool(opts.allTools, selected, opts.skillCatalog));
|
|
8328
|
-
|
|
8330
|
+
seen.add("discover_tools");
|
|
8331
|
+
const pushUnique = (tool) => {
|
|
8332
|
+
if (!seen.has(tool.name)) {
|
|
8333
|
+
seen.add(tool.name);
|
|
8334
|
+
result.push(tool);
|
|
8335
|
+
}
|
|
8336
|
+
};
|
|
8337
|
+
pushUnique({
|
|
8329
8338
|
name: "notify_user",
|
|
8330
8339
|
description: "Send a message to the user. The message appears in the agent chat and as a notification. Write a comprehensive body \u2014 the user sees the full content and may reply. Use for status updates, reports, alerts, and findings.",
|
|
8331
8340
|
inputSchema: {
|
|
@@ -8339,7 +8348,7 @@ var init_tool_selector = __esm({
|
|
|
8339
8348
|
required: ["title", "body"]
|
|
8340
8349
|
}
|
|
8341
8350
|
});
|
|
8342
|
-
|
|
8351
|
+
pushUnique({
|
|
8343
8352
|
name: "request_user_approval",
|
|
8344
8353
|
description: "Request a decision or approval from the user. The tool BLOCKS until the user responds. Use when you need human approval, a choice between options, or any user decision/input. Default options: Approve / Reject (reject requires a reason). You can provide custom options and optionally allow freeform text input.",
|
|
8345
8354
|
inputSchema: {
|
|
@@ -8367,7 +8376,7 @@ var init_tool_selector = __esm({
|
|
|
8367
8376
|
required: ["title", "description"]
|
|
8368
8377
|
}
|
|
8369
8378
|
});
|
|
8370
|
-
|
|
8379
|
+
pushUnique({
|
|
8371
8380
|
name: "recall_activity",
|
|
8372
8381
|
description: 'Query your own execution history. Use "list" to see recent activities, or "get" with an activity_id to see detailed tool call logs for a specific activity.',
|
|
8373
8382
|
inputSchema: {
|
|
@@ -8668,7 +8677,7 @@ function createShellTool(security, workspacePath, agentMeta, policy, onCommandAp
|
|
|
8668
8677
|
}
|
|
8669
8678
|
}
|
|
8670
8679
|
const finalCommand = injectGitCommitMeta(command, agentMeta);
|
|
8671
|
-
return new Promise((
|
|
8680
|
+
return new Promise((resolve20) => {
|
|
8672
8681
|
const child = spawn("sh", ["-c", finalCommand], {
|
|
8673
8682
|
cwd: effectiveCwd ?? void 0,
|
|
8674
8683
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -8723,7 +8732,7 @@ function createShellTool(security, workspacePath, agentMeta, policy, onCommandAp
|
|
|
8723
8732
|
flushOutput();
|
|
8724
8733
|
}
|
|
8725
8734
|
if (killed) {
|
|
8726
|
-
|
|
8735
|
+
resolve20(JSON.stringify({
|
|
8727
8736
|
status: "error",
|
|
8728
8737
|
error: `Command timed out after ${timeoutMs}ms`,
|
|
8729
8738
|
exitCode: code,
|
|
@@ -8731,7 +8740,7 @@ function createShellTool(security, workspacePath, agentMeta, policy, onCommandAp
|
|
|
8731
8740
|
stderr: stderr.slice(0, 4e3)
|
|
8732
8741
|
}));
|
|
8733
8742
|
} else if (code !== 0) {
|
|
8734
|
-
|
|
8743
|
+
resolve20(JSON.stringify({
|
|
8735
8744
|
status: "error",
|
|
8736
8745
|
error: stderr.trim() || `Process exited with code ${code}`,
|
|
8737
8746
|
exitCode: code,
|
|
@@ -8739,7 +8748,7 @@ function createShellTool(security, workspacePath, agentMeta, policy, onCommandAp
|
|
|
8739
8748
|
stderr: stderr.slice(0, 4e3)
|
|
8740
8749
|
}));
|
|
8741
8750
|
} else {
|
|
8742
|
-
|
|
8751
|
+
resolve20(JSON.stringify({
|
|
8743
8752
|
status: "success",
|
|
8744
8753
|
stdout: stdout.trim() || void 0,
|
|
8745
8754
|
stderr: stderr.trim() || void 0
|
|
@@ -8752,7 +8761,7 @@ function createShellTool(security, workspacePath, agentMeta, policy, onCommandAp
|
|
|
8752
8761
|
clearTimeout(flushTimer);
|
|
8753
8762
|
flushOutput();
|
|
8754
8763
|
}
|
|
8755
|
-
|
|
8764
|
+
resolve20(JSON.stringify({
|
|
8756
8765
|
status: "error",
|
|
8757
8766
|
error: err.message,
|
|
8758
8767
|
stdout: stdout.slice(0, 4e3),
|
|
@@ -14852,8 +14861,8 @@ var init_custom_element_registry = __esm({
|
|
|
14852
14861
|
} : (element) => element.localName === localName;
|
|
14853
14862
|
registry.set(localName, { Class, check: check2 });
|
|
14854
14863
|
if (waiting.has(localName)) {
|
|
14855
|
-
for (const
|
|
14856
|
-
|
|
14864
|
+
for (const resolve20 of waiting.get(localName))
|
|
14865
|
+
resolve20(Class);
|
|
14857
14866
|
waiting.delete(localName);
|
|
14858
14867
|
}
|
|
14859
14868
|
ownerDocument.querySelectorAll(
|
|
@@ -14893,13 +14902,13 @@ var init_custom_element_registry = __esm({
|
|
|
14893
14902
|
*/
|
|
14894
14903
|
whenDefined(localName) {
|
|
14895
14904
|
const { registry, waiting } = this;
|
|
14896
|
-
return new Promise((
|
|
14905
|
+
return new Promise((resolve20) => {
|
|
14897
14906
|
if (registry.has(localName))
|
|
14898
|
-
|
|
14907
|
+
resolve20(registry.get(localName).Class);
|
|
14899
14908
|
else {
|
|
14900
14909
|
if (!waiting.has(localName))
|
|
14901
14910
|
waiting.set(localName, []);
|
|
14902
|
-
waiting.get(localName).push(
|
|
14911
|
+
waiting.get(localName).push(resolve20);
|
|
14903
14912
|
}
|
|
14904
14913
|
});
|
|
14905
14914
|
}
|
|
@@ -41801,7 +41810,7 @@ var init_search = __esm({
|
|
|
41801
41810
|
|
|
41802
41811
|
// ../core/dist/tools/patch.js
|
|
41803
41812
|
import { readFileSync as readFileSync9, writeFileSync as writeFileSync7, mkdirSync as mkdirSync8, existsSync as existsSync13, unlinkSync } from "node:fs";
|
|
41804
|
-
import { dirname as dirname4
|
|
41813
|
+
import { dirname as dirname4 } from "node:path";
|
|
41805
41814
|
function createPatchTool(security, workspacePath, policy) {
|
|
41806
41815
|
const guard = security ?? defaultSecurityGuard;
|
|
41807
41816
|
return {
|
|
@@ -41852,7 +41861,7 @@ function createPatchTool(security, workspacePath, policy) {
|
|
|
41852
41861
|
if (!patches || !Array.isArray(patches) || patches.length === 0) {
|
|
41853
41862
|
return JSON.stringify({ status: "error", error: "patches array is required and must not be empty" });
|
|
41854
41863
|
}
|
|
41855
|
-
const
|
|
41864
|
+
const resolvedPaths = [];
|
|
41856
41865
|
const results = [];
|
|
41857
41866
|
for (const patch of patches) {
|
|
41858
41867
|
const { resolved: filePath, access } = resolveAndCheckAccess(patch.file, workspacePath, policy);
|
|
@@ -41893,6 +41902,7 @@ function createPatchTool(security, workspacePath, policy) {
|
|
|
41893
41902
|
if (patch.action === "create" && !patch.content && patch.content !== "") {
|
|
41894
41903
|
return JSON.stringify({ status: "error", error: `create action requires content for ${patch.file}` });
|
|
41895
41904
|
}
|
|
41905
|
+
resolvedPaths.push(filePath);
|
|
41896
41906
|
}
|
|
41897
41907
|
if (dryRun) {
|
|
41898
41908
|
return JSON.stringify({
|
|
@@ -41901,8 +41911,9 @@ function createPatchTool(security, workspacePath, policy) {
|
|
|
41901
41911
|
patchCount: patches.length
|
|
41902
41912
|
});
|
|
41903
41913
|
}
|
|
41904
|
-
for (
|
|
41905
|
-
const
|
|
41914
|
+
for (let i = 0; i < patches.length; i++) {
|
|
41915
|
+
const patch = patches[i];
|
|
41916
|
+
const filePath = resolvedPaths[i];
|
|
41906
41917
|
switch (patch.action) {
|
|
41907
41918
|
case "edit": {
|
|
41908
41919
|
let content = readFileSync9(filePath, "utf-8");
|
|
@@ -41958,7 +41969,7 @@ var init_patch = __esm({
|
|
|
41958
41969
|
|
|
41959
41970
|
// ../core/dist/tools/process-manager.js
|
|
41960
41971
|
import { spawn as spawn2 } from "node:child_process";
|
|
41961
|
-
import { resolve as
|
|
41972
|
+
import { resolve as resolve7 } from "node:path";
|
|
41962
41973
|
function onBackgroundCompletion(cb) {
|
|
41963
41974
|
completionListeners.push(cb);
|
|
41964
41975
|
return () => {
|
|
@@ -42020,8 +42031,8 @@ function createBackgroundExecTool(workspacePath) {
|
|
|
42020
42031
|
const cwd = args["cwd"];
|
|
42021
42032
|
const timeoutSec = args["timeout_seconds"] ?? 300;
|
|
42022
42033
|
const basePath = workspacePath ?? process.cwd();
|
|
42023
|
-
const effectiveCwd = cwd ?
|
|
42024
|
-
if (workspacePath && !effectiveCwd.startsWith(
|
|
42034
|
+
const effectiveCwd = cwd ? resolve7(basePath, cwd) : basePath;
|
|
42035
|
+
if (workspacePath && !effectiveCwd.startsWith(resolve7(workspacePath))) {
|
|
42025
42036
|
return JSON.stringify({ status: "denied", error: "Working directory must be within workspace" });
|
|
42026
42037
|
}
|
|
42027
42038
|
const id = `bg_${++sessionCounter}_${Date.now()}`;
|
|
@@ -42285,7 +42296,7 @@ async function llmCallWithRetry(fn, label) {
|
|
|
42285
42296
|
error: String(err).slice(0, SUBAGENT_ERROR_PREVIEW_CHARS),
|
|
42286
42297
|
delay
|
|
42287
42298
|
});
|
|
42288
|
-
await new Promise((
|
|
42299
|
+
await new Promise((resolve20) => setTimeout(resolve20, delay));
|
|
42289
42300
|
}
|
|
42290
42301
|
}
|
|
42291
42302
|
throw lastErr;
|
|
@@ -42358,7 +42369,7 @@ async function runSubagentLoop(ctx, task, opts) {
|
|
|
42358
42369
|
metadata: { iteration: iterations, finishReason: response.finishReason }
|
|
42359
42370
|
});
|
|
42360
42371
|
if (response.finishReason === "max_tokens" && !response.toolCalls?.length) {
|
|
42361
|
-
messages.push({ role: "assistant", content: response.content });
|
|
42372
|
+
messages.push({ role: "assistant", content: response.content, reasoningContent: response.reasoningContent });
|
|
42362
42373
|
logEntries.push({ ts: (/* @__PURE__ */ new Date()).toISOString(), role: "assistant", content: response.content });
|
|
42363
42374
|
messages.push({
|
|
42364
42375
|
role: "user",
|
|
@@ -42368,7 +42379,8 @@ async function runSubagentLoop(ctx, task, opts) {
|
|
|
42368
42379
|
messages.push({
|
|
42369
42380
|
role: "assistant",
|
|
42370
42381
|
content: response.content,
|
|
42371
|
-
toolCalls: response.toolCalls
|
|
42382
|
+
toolCalls: response.toolCalls,
|
|
42383
|
+
reasoningContent: response.reasoningContent
|
|
42372
42384
|
});
|
|
42373
42385
|
logEntries.push({
|
|
42374
42386
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -42873,9 +42885,9 @@ ${typeLabel}${item.payload.content}`;
|
|
|
42873
42885
|
*/
|
|
42874
42886
|
wakeIdleLoop() {
|
|
42875
42887
|
if (this.idleResolve) {
|
|
42876
|
-
const
|
|
42888
|
+
const resolve20 = this.idleResolve;
|
|
42877
42889
|
this.idleResolve = void 0;
|
|
42878
|
-
|
|
42890
|
+
resolve20();
|
|
42879
42891
|
}
|
|
42880
42892
|
}
|
|
42881
42893
|
/**
|
|
@@ -42900,8 +42912,8 @@ ${typeLabel}${item.payload.content}`;
|
|
|
42900
42912
|
const item = this.dequeue();
|
|
42901
42913
|
if (item)
|
|
42902
42914
|
return item;
|
|
42903
|
-
await new Promise((
|
|
42904
|
-
this.idleResolve =
|
|
42915
|
+
await new Promise((resolve20) => {
|
|
42916
|
+
this.idleResolve = resolve20;
|
|
42905
42917
|
});
|
|
42906
42918
|
const afterWake = this.dequeue();
|
|
42907
42919
|
if (!afterWake) {
|
|
@@ -43448,7 +43460,7 @@ var init_attention = __esm({
|
|
|
43448
43460
|
try {
|
|
43449
43461
|
const processing = this.delegate?.processMailboxItem(item);
|
|
43450
43462
|
const backstopMs = this.waitingForHumanApproval ? APPROVAL_WAIT_TIMEOUT_MS : MAILBOX_PROCESSING_TIMEOUT_MS;
|
|
43451
|
-
const backstop = new Promise((
|
|
43463
|
+
const backstop = new Promise((resolve20) => setTimeout(() => resolve20(void 0), backstopMs));
|
|
43452
43464
|
const result = await Promise.race([
|
|
43453
43465
|
processing?.then((r) => ({ done: true, reply: r })),
|
|
43454
43466
|
backstop.then(() => ({ done: false, reply: void 0 }))
|
|
@@ -43554,8 +43566,8 @@ var init_attention = __esm({
|
|
|
43554
43566
|
* The promise is single-use; call again to get a fresh one.
|
|
43555
43567
|
*/
|
|
43556
43568
|
waitForPreemptionSignal() {
|
|
43557
|
-
return new Promise((
|
|
43558
|
-
this.criticalInterruptResolve =
|
|
43569
|
+
return new Promise((resolve20) => {
|
|
43570
|
+
this.criticalInterruptResolve = resolve20;
|
|
43559
43571
|
});
|
|
43560
43572
|
}
|
|
43561
43573
|
/**
|
|
@@ -43802,7 +43814,7 @@ var init_attention = __esm({
|
|
|
43802
43814
|
raw = response.content;
|
|
43803
43815
|
break;
|
|
43804
43816
|
}
|
|
43805
|
-
messages.push({ role: "assistant", content: response.content, toolCalls: response.toolCalls });
|
|
43817
|
+
messages.push({ role: "assistant", content: response.content, toolCalls: response.toolCalls, reasoningContent: response.reasoningContent });
|
|
43806
43818
|
for (const tc of response.toolCalls) {
|
|
43807
43819
|
const handler4 = this.triageToolHandlers.get(tc.name);
|
|
43808
43820
|
let result;
|
|
@@ -44302,7 +44314,7 @@ var init_task_queue = __esm({
|
|
|
44302
44314
|
*/
|
|
44303
44315
|
async waitForAll() {
|
|
44304
44316
|
while (this.runningTasks.size > 0 || this.queue.length > 0) {
|
|
44305
|
-
await new Promise((
|
|
44317
|
+
await new Promise((resolve20) => setTimeout(resolve20, 100));
|
|
44306
44318
|
}
|
|
44307
44319
|
}
|
|
44308
44320
|
};
|
|
@@ -44429,12 +44441,12 @@ var init_task_executor = __esm({
|
|
|
44429
44441
|
* 等待任务完成
|
|
44430
44442
|
*/
|
|
44431
44443
|
async waitForTaskCompletion(taskId2) {
|
|
44432
|
-
return new Promise((
|
|
44444
|
+
return new Promise((resolve20) => {
|
|
44433
44445
|
const checkInterval = setInterval(() => {
|
|
44434
44446
|
const task = this.taskQueue.getTaskStatus(taskId2);
|
|
44435
44447
|
if (task && task.status !== TaskStatus.PENDING && task.status !== TaskStatus.RUNNING) {
|
|
44436
44448
|
clearInterval(checkInterval);
|
|
44437
|
-
|
|
44449
|
+
resolve20(task);
|
|
44438
44450
|
}
|
|
44439
44451
|
}, 100);
|
|
44440
44452
|
});
|
|
@@ -44938,24 +44950,24 @@ function extensionForMime(mime) {
|
|
|
44938
44950
|
async function checkMarkitdown() {
|
|
44939
44951
|
if (markitdownAvailable !== null)
|
|
44940
44952
|
return markitdownAvailable;
|
|
44941
|
-
return new Promise((
|
|
44953
|
+
return new Promise((resolve20) => {
|
|
44942
44954
|
execFile2("markitdown", ["--help"], { timeout: 5e3 }, (err) => {
|
|
44943
44955
|
markitdownAvailable = !err;
|
|
44944
44956
|
if (!markitdownAvailable) {
|
|
44945
44957
|
log16.info('markitdown CLI not found; file-to-text conversion will be limited. Install with: pip install "markitdown[all]"');
|
|
44946
44958
|
}
|
|
44947
|
-
|
|
44959
|
+
resolve20(markitdownAvailable);
|
|
44948
44960
|
});
|
|
44949
44961
|
});
|
|
44950
44962
|
}
|
|
44951
44963
|
async function convertWithMarkitdown(filePath) {
|
|
44952
|
-
return new Promise((
|
|
44964
|
+
return new Promise((resolve20, reject) => {
|
|
44953
44965
|
execFile2("markitdown", [filePath], { timeout: 3e4, maxBuffer: 10 * 1024 * 1024 }, (err, stdout, stderr) => {
|
|
44954
44966
|
if (err) {
|
|
44955
44967
|
reject(new Error(`markitdown failed: ${stderr || err.message}`));
|
|
44956
44968
|
return;
|
|
44957
44969
|
}
|
|
44958
|
-
|
|
44970
|
+
resolve20(stdout);
|
|
44959
44971
|
});
|
|
44960
44972
|
});
|
|
44961
44973
|
}
|
|
@@ -45414,14 +45426,14 @@ ${notification.stdoutTail}`);
|
|
|
45414
45426
|
toolEventCollector: options?.toolEventCollector
|
|
45415
45427
|
}
|
|
45416
45428
|
};
|
|
45417
|
-
return new Promise((
|
|
45429
|
+
return new Promise((resolve20, reject) => {
|
|
45418
45430
|
this.mailbox.enqueue(sourceType, payload, {
|
|
45419
45431
|
priority: options?.priority,
|
|
45420
45432
|
metadata: {
|
|
45421
45433
|
senderId,
|
|
45422
45434
|
senderName: senderInfo?.name,
|
|
45423
45435
|
senderRole: senderInfo?.role,
|
|
45424
|
-
responsePromise: { resolve:
|
|
45436
|
+
responsePromise: { resolve: resolve20, reject }
|
|
45425
45437
|
}
|
|
45426
45438
|
});
|
|
45427
45439
|
});
|
|
@@ -45443,14 +45455,14 @@ ${notification.stdoutTail}`);
|
|
|
45443
45455
|
cancelToken
|
|
45444
45456
|
}
|
|
45445
45457
|
};
|
|
45446
|
-
return new Promise((
|
|
45458
|
+
return new Promise((resolve20, reject) => {
|
|
45447
45459
|
this.mailbox.enqueue("human_chat", payload, {
|
|
45448
45460
|
priority: 0,
|
|
45449
45461
|
metadata: {
|
|
45450
45462
|
senderId,
|
|
45451
45463
|
senderName: senderInfo?.name,
|
|
45452
45464
|
senderRole: senderInfo?.role,
|
|
45453
|
-
responsePromise: { resolve:
|
|
45465
|
+
responsePromise: { resolve: resolve20, reject }
|
|
45454
45466
|
}
|
|
45455
45467
|
});
|
|
45456
45468
|
});
|
|
@@ -45478,12 +45490,12 @@ ${notification.stdoutTail}`);
|
|
|
45478
45490
|
executionRound
|
|
45479
45491
|
}
|
|
45480
45492
|
};
|
|
45481
|
-
return new Promise((
|
|
45493
|
+
return new Promise((resolve20, reject) => {
|
|
45482
45494
|
this.mailbox.enqueue("task_status_update", payload, {
|
|
45483
45495
|
priority: 1,
|
|
45484
45496
|
metadata: {
|
|
45485
45497
|
taskId: taskId2,
|
|
45486
|
-
responsePromise: { resolve:
|
|
45498
|
+
responsePromise: { resolve: resolve20, reject }
|
|
45487
45499
|
}
|
|
45488
45500
|
});
|
|
45489
45501
|
});
|
|
@@ -45501,13 +45513,13 @@ ${notification.stdoutTail}`);
|
|
|
45501
45513
|
onLog
|
|
45502
45514
|
}
|
|
45503
45515
|
};
|
|
45504
|
-
return new Promise((
|
|
45516
|
+
return new Promise((resolve20, reject) => {
|
|
45505
45517
|
this.mailbox.enqueue("session_reply", payload, {
|
|
45506
45518
|
metadata: {
|
|
45507
45519
|
senderId,
|
|
45508
45520
|
senderName: senderInfo?.name,
|
|
45509
45521
|
senderRole: senderInfo?.role,
|
|
45510
|
-
responsePromise: { resolve:
|
|
45522
|
+
responsePromise: { resolve: resolve20, reject }
|
|
45511
45523
|
}
|
|
45512
45524
|
});
|
|
45513
45525
|
});
|
|
@@ -46891,7 +46903,7 @@ ${block}
|
|
|
46891
46903
|
break;
|
|
46892
46904
|
}
|
|
46893
46905
|
if (response.finishReason === "max_tokens" && !response.toolCalls?.length) {
|
|
46894
|
-
this.memory.appendMessage(sessionId, { role: "assistant", content: response.content });
|
|
46906
|
+
this.memory.appendMessage(sessionId, { role: "assistant", content: response.content, reasoningContent: response.reasoningContent });
|
|
46895
46907
|
const contMsg = {
|
|
46896
46908
|
role: "user",
|
|
46897
46909
|
content: "[Continue from where you left off. Do not repeat what you already said.]"
|
|
@@ -46901,7 +46913,8 @@ ${block}
|
|
|
46901
46913
|
this.memory.appendMessage(sessionId, {
|
|
46902
46914
|
role: "assistant",
|
|
46903
46915
|
content: response.content,
|
|
46904
|
-
toolCalls: response.toolCalls
|
|
46916
|
+
toolCalls: response.toolCalls,
|
|
46917
|
+
reasoningContent: response.reasoningContent
|
|
46905
46918
|
});
|
|
46906
46919
|
const currentActId = this.state.currentActivity?.id;
|
|
46907
46920
|
const toolResults = await Promise.all(response.toolCalls.map(async (tc) => {
|
|
@@ -47043,10 +47056,10 @@ ${chatYield.item.payload.content}`;
|
|
|
47043
47056
|
const outputCheck = await this.guardrails.checkOutput(displayReply, { agentId: this.id });
|
|
47044
47057
|
if (!outputCheck.passed) {
|
|
47045
47058
|
const filtered = `[Response filtered: ${outputCheck.reason}]`;
|
|
47046
|
-
this.memory.appendMessage(sessionId, { role: "assistant", content: filtered });
|
|
47059
|
+
this.memory.appendMessage(sessionId, { role: "assistant", content: filtered, reasoningContent: response.reasoningContent });
|
|
47047
47060
|
return filtered;
|
|
47048
47061
|
}
|
|
47049
|
-
this.memory.appendMessage(sessionId, { role: "assistant", content: displayReply });
|
|
47062
|
+
this.memory.appendMessage(sessionId, { role: "assistant", content: displayReply, reasoningContent: response.reasoningContent });
|
|
47050
47063
|
if (!isLightweight && displayReply.length > 50 && senderId) {
|
|
47051
47064
|
this.memory.writeDailyLog(this.id, `[Chat with ${senderInfo?.name ?? senderId}] Q: ${userMessage.slice(0, 150)}... A: ${displayReply.slice(0, 300)}`);
|
|
47052
47065
|
}
|
|
@@ -47219,7 +47232,8 @@ ${chatYield.item.payload.content}`;
|
|
|
47219
47232
|
if (response.finishReason === "max_tokens" && !response.toolCalls?.length) {
|
|
47220
47233
|
this.memory.appendMessage(this.currentSessionId, {
|
|
47221
47234
|
role: "assistant",
|
|
47222
|
-
content: response.content
|
|
47235
|
+
content: response.content,
|
|
47236
|
+
reasoningContent: response.reasoningContent
|
|
47223
47237
|
});
|
|
47224
47238
|
this.memory.appendMessage(this.currentSessionId, {
|
|
47225
47239
|
role: "user",
|
|
@@ -47229,7 +47243,8 @@ ${chatYield.item.payload.content}`;
|
|
|
47229
47243
|
this.memory.appendMessage(this.currentSessionId, {
|
|
47230
47244
|
role: "assistant",
|
|
47231
47245
|
content: response.content,
|
|
47232
|
-
toolCalls: response.toolCalls
|
|
47246
|
+
toolCalls: response.toolCalls,
|
|
47247
|
+
reasoningContent: response.reasoningContent
|
|
47233
47248
|
});
|
|
47234
47249
|
const subagentProgressCb = (event) => {
|
|
47235
47250
|
onEvent({
|
|
@@ -47351,10 +47366,10 @@ ${chatYield.item.payload.content}`;
|
|
|
47351
47366
|
const outputCheck = await this.guardrails.checkOutput(displayReply, { agentId: this.id });
|
|
47352
47367
|
if (!outputCheck.passed) {
|
|
47353
47368
|
const filtered = `[Response filtered: ${outputCheck.reason}]`;
|
|
47354
|
-
this.memory.appendMessage(this.currentSessionId, { role: "assistant", content: filtered });
|
|
47369
|
+
this.memory.appendMessage(this.currentSessionId, { role: "assistant", content: filtered, reasoningContent: response.reasoningContent });
|
|
47355
47370
|
return filtered;
|
|
47356
47371
|
}
|
|
47357
|
-
this.memory.appendMessage(this.currentSessionId, { role: "assistant", content: displayReply });
|
|
47372
|
+
this.memory.appendMessage(this.currentSessionId, { role: "assistant", content: displayReply, reasoningContent: response.reasoningContent });
|
|
47358
47373
|
if (streamChatActivityId && thinkingBuffer.trim()) {
|
|
47359
47374
|
this.emitActivityLog(streamChatActivityId, "text", thinkingBuffer, { isThinking: true });
|
|
47360
47375
|
}
|
|
@@ -47637,7 +47652,7 @@ ${chatYield.item.payload.content}`;
|
|
|
47637
47652
|
}
|
|
47638
47653
|
flushText();
|
|
47639
47654
|
if (response.finishReason === "max_tokens" && !response.toolCalls?.length) {
|
|
47640
|
-
this.memory.appendMessage(sessionId, { role: "assistant", content: response.content });
|
|
47655
|
+
this.memory.appendMessage(sessionId, { role: "assistant", content: response.content, reasoningContent: response.reasoningContent });
|
|
47641
47656
|
this.memory.appendMessage(sessionId, {
|
|
47642
47657
|
role: "user",
|
|
47643
47658
|
content: "[Continue from where you left off. Do not repeat what you already said.]"
|
|
@@ -47646,7 +47661,8 @@ ${chatYield.item.payload.content}`;
|
|
|
47646
47661
|
this.memory.appendMessage(sessionId, {
|
|
47647
47662
|
role: "assistant",
|
|
47648
47663
|
content: response.content,
|
|
47649
|
-
toolCalls: response.toolCalls
|
|
47664
|
+
toolCalls: response.toolCalls,
|
|
47665
|
+
reasoningContent: response.reasoningContent
|
|
47650
47666
|
});
|
|
47651
47667
|
let interruptedDuringTools = false;
|
|
47652
47668
|
for (const tc of response.toolCalls) {
|
|
@@ -47833,7 +47849,7 @@ ${yieldResult.item.payload.content}`
|
|
|
47833
47849
|
if (!didSubmitReview && !cancelToken?.cancelled) {
|
|
47834
47850
|
log17.warn("Task execution ending without task_submit_review \u2014 injecting final reminder", { taskId: taskId2, agentId: this.id });
|
|
47835
47851
|
flushText();
|
|
47836
|
-
this.memory.appendMessage(sessionId, { role: "assistant", content: response.content });
|
|
47852
|
+
this.memory.appendMessage(sessionId, { role: "assistant", content: response.content, reasoningContent: response.reasoningContent });
|
|
47837
47853
|
this.memory.appendMessage(sessionId, {
|
|
47838
47854
|
role: "user",
|
|
47839
47855
|
content: [
|
|
@@ -47878,7 +47894,8 @@ ${yieldResult.item.payload.content}`
|
|
|
47878
47894
|
this.memory.appendMessage(sessionId, {
|
|
47879
47895
|
role: "assistant",
|
|
47880
47896
|
content: response.content,
|
|
47881
|
-
toolCalls: response.toolCalls
|
|
47897
|
+
toolCalls: response.toolCalls,
|
|
47898
|
+
reasoningContent: response.reasoningContent
|
|
47882
47899
|
});
|
|
47883
47900
|
for (const tc of response.toolCalls) {
|
|
47884
47901
|
if (cancelToken?.cancelled)
|
|
@@ -47910,12 +47927,12 @@ ${yieldResult.item.payload.content}`
|
|
|
47910
47927
|
} else {
|
|
47911
47928
|
flushText();
|
|
47912
47929
|
const finalReply = stripCompletionMarker(sanitizeLLMReply(response.content));
|
|
47913
|
-
this.memory.appendMessage(sessionId, { role: "assistant", content: finalReply });
|
|
47930
|
+
this.memory.appendMessage(sessionId, { role: "assistant", content: finalReply, reasoningContent: response.reasoningContent });
|
|
47914
47931
|
}
|
|
47915
47932
|
} else {
|
|
47916
47933
|
flushText();
|
|
47917
47934
|
const finalReply = stripCompletionMarker(sanitizeLLMReply(response.content));
|
|
47918
|
-
this.memory.appendMessage(sessionId, { role: "assistant", content: finalReply });
|
|
47935
|
+
this.memory.appendMessage(sessionId, { role: "assistant", content: finalReply, reasoningContent: response.reasoningContent });
|
|
47919
47936
|
}
|
|
47920
47937
|
emit("status", "execution_finished", {});
|
|
47921
47938
|
this.metricsCollector.recordTaskCompletion(taskId2, "completed", Date.now() - taskStartMs);
|
|
@@ -48054,7 +48071,7 @@ ${yieldResult.item.payload.content}`
|
|
|
48054
48071
|
break;
|
|
48055
48072
|
flushText();
|
|
48056
48073
|
if (response.finishReason === "max_tokens" && !response.toolCalls?.length) {
|
|
48057
|
-
this.memory.appendMessage(sessionId, { role: "assistant", content: response.content });
|
|
48074
|
+
this.memory.appendMessage(sessionId, { role: "assistant", content: response.content, reasoningContent: response.reasoningContent });
|
|
48058
48075
|
this.memory.appendMessage(sessionId, {
|
|
48059
48076
|
role: "user",
|
|
48060
48077
|
content: "[Continue from where you left off. Do not repeat what you already said.]"
|
|
@@ -48063,7 +48080,8 @@ ${yieldResult.item.payload.content}`
|
|
|
48063
48080
|
this.memory.appendMessage(sessionId, {
|
|
48064
48081
|
role: "assistant",
|
|
48065
48082
|
content: response.content,
|
|
48066
|
-
toolCalls: response.toolCalls
|
|
48083
|
+
toolCalls: response.toolCalls,
|
|
48084
|
+
reasoningContent: response.reasoningContent
|
|
48067
48085
|
});
|
|
48068
48086
|
for (const tc of response.toolCalls) {
|
|
48069
48087
|
if (this.attentionController.hasInterruptPending()) {
|
|
@@ -48117,7 +48135,7 @@ ${yieldResult.item.payload.content}`
|
|
|
48117
48135
|
flushText();
|
|
48118
48136
|
const rawReply = sanitizeLLMReply(response.content);
|
|
48119
48137
|
const displayReply = stripCompletionMarker(rawReply);
|
|
48120
|
-
this.memory.appendMessage(sessionId, { role: "assistant", content: displayReply });
|
|
48138
|
+
this.memory.appendMessage(sessionId, { role: "assistant", content: displayReply, reasoningContent: response.reasoningContent });
|
|
48121
48139
|
return rawReply;
|
|
48122
48140
|
} catch (error) {
|
|
48123
48141
|
if (textBuffer.trim()) {
|
|
@@ -48637,7 +48655,7 @@ ${escalationReason}`;
|
|
|
48637
48655
|
error: String(error).slice(0, 200),
|
|
48638
48656
|
delay
|
|
48639
48657
|
});
|
|
48640
|
-
await new Promise((
|
|
48658
|
+
await new Promise((resolve20) => setTimeout(resolve20, delay));
|
|
48641
48659
|
}
|
|
48642
48660
|
}
|
|
48643
48661
|
throw lastError;
|
|
@@ -48913,7 +48931,7 @@ ${todayLog.slice(0, HEARTBEAT_DAILY_LOG_CHARS)}
|
|
|
48913
48931
|
agentId: this.id,
|
|
48914
48932
|
error: String(error).slice(0, 200)
|
|
48915
48933
|
});
|
|
48916
|
-
await new Promise((
|
|
48934
|
+
await new Promise((resolve20) => setTimeout(resolve20, delay));
|
|
48917
48935
|
}
|
|
48918
48936
|
}
|
|
48919
48937
|
}
|
|
@@ -49207,7 +49225,7 @@ ${promo.content}` : promo.content;
|
|
|
49207
49225
|
|
|
49208
49226
|
// ../core/dist/role-loader.js
|
|
49209
49227
|
import { readFileSync as readFileSync11, existsSync as existsSync16, readdirSync as readdirSync3 } from "node:fs";
|
|
49210
|
-
import { join as join11, resolve as
|
|
49228
|
+
import { join as join11, resolve as resolve8 } from "node:path";
|
|
49211
49229
|
var RoleLoader;
|
|
49212
49230
|
var init_role_loader = __esm({
|
|
49213
49231
|
"../core/dist/role-loader.js"() {
|
|
@@ -49216,7 +49234,7 @@ var init_role_loader = __esm({
|
|
|
49216
49234
|
RoleLoader = class {
|
|
49217
49235
|
templateDirs;
|
|
49218
49236
|
constructor(templateDirs) {
|
|
49219
|
-
this.templateDirs = templateDirs ?? [
|
|
49237
|
+
this.templateDirs = templateDirs ?? [resolve8(process.cwd(), "templates", "roles")];
|
|
49220
49238
|
}
|
|
49221
49239
|
getTemplateDirs() {
|
|
49222
49240
|
return this.templateDirs;
|
|
@@ -49556,7 +49574,7 @@ var init_mcp_client = __esm({
|
|
|
49556
49574
|
}
|
|
49557
49575
|
}
|
|
49558
49576
|
sendRequest(proc, method, params) {
|
|
49559
|
-
return new Promise((
|
|
49577
|
+
return new Promise((resolve20, reject) => {
|
|
49560
49578
|
const id = ++this.requestId;
|
|
49561
49579
|
const message = JSON.stringify({ jsonrpc: "2.0", id, method, params }) + "\n";
|
|
49562
49580
|
const timeoutMs = method === "tools/call" ? 12e4 : 3e4;
|
|
@@ -49564,7 +49582,7 @@ var init_mcp_client = __esm({
|
|
|
49564
49582
|
this.pendingRequests.delete(id);
|
|
49565
49583
|
reject(new Error(`MCP request timeout for ${method} (id=${id}, ${timeoutMs}ms)`));
|
|
49566
49584
|
}, timeoutMs);
|
|
49567
|
-
this.pendingRequests.set(id, { resolve:
|
|
49585
|
+
this.pendingRequests.set(id, { resolve: resolve20, reject, method, timer, proc });
|
|
49568
49586
|
proc.stdin?.write(message);
|
|
49569
49587
|
});
|
|
49570
49588
|
}
|
|
@@ -52385,11 +52403,11 @@ function createSettingsTools(ctx) {
|
|
|
52385
52403
|
},
|
|
52386
52404
|
base_url: {
|
|
52387
52405
|
type: "string",
|
|
52388
|
-
description: 'Optional base URL for the API (e.g. "https://api.deepseek.com
|
|
52406
|
+
description: 'Optional base URL for the API (e.g. "https://api.deepseek.com")'
|
|
52389
52407
|
},
|
|
52390
52408
|
model: {
|
|
52391
52409
|
type: "string",
|
|
52392
|
-
description: 'Default model ID (e.g. "deepseek-
|
|
52410
|
+
description: 'Default model ID (e.g. "deepseek-v4-flash")'
|
|
52393
52411
|
}
|
|
52394
52412
|
},
|
|
52395
52413
|
required: ["name", "model"]
|
|
@@ -52514,7 +52532,7 @@ function createSettingsTools(ctx) {
|
|
|
52514
52532
|
},
|
|
52515
52533
|
id: {
|
|
52516
52534
|
type: "string",
|
|
52517
|
-
description: 'Model ID (e.g. "deepseek-
|
|
52535
|
+
description: 'Model ID (e.g. "deepseek-v4-flash")'
|
|
52518
52536
|
},
|
|
52519
52537
|
name: {
|
|
52520
52538
|
type: "string",
|
|
@@ -55477,7 +55495,7 @@ var init_openai = __esm({
|
|
|
55477
55495
|
};
|
|
55478
55496
|
}
|
|
55479
55497
|
if (m.toolCalls?.length) {
|
|
55480
|
-
|
|
55498
|
+
const msg = {
|
|
55481
55499
|
role: "assistant",
|
|
55482
55500
|
content: getTextContent(m.content) || null,
|
|
55483
55501
|
tool_calls: m.toolCalls.map((tc) => ({
|
|
@@ -55486,6 +55504,17 @@ var init_openai = __esm({
|
|
|
55486
55504
|
function: { name: tc.name, arguments: JSON.stringify(tc.arguments) }
|
|
55487
55505
|
}))
|
|
55488
55506
|
};
|
|
55507
|
+
if (m.reasoningContent)
|
|
55508
|
+
msg.reasoning_content = m.reasoningContent;
|
|
55509
|
+
return msg;
|
|
55510
|
+
}
|
|
55511
|
+
if (m.role === "assistant" && m.reasoningContent) {
|
|
55512
|
+
const msg = {
|
|
55513
|
+
role: "assistant",
|
|
55514
|
+
content: typeof m.content === "string" ? m.content : getTextContent(m.content),
|
|
55515
|
+
reasoning_content: m.reasoningContent
|
|
55516
|
+
};
|
|
55517
|
+
return msg;
|
|
55489
55518
|
}
|
|
55490
55519
|
if (Array.isArray(m.content)) {
|
|
55491
55520
|
return {
|
|
@@ -55497,14 +55526,22 @@ var init_openai = __esm({
|
|
|
55497
55526
|
});
|
|
55498
55527
|
}
|
|
55499
55528
|
convertTools(tools) {
|
|
55500
|
-
|
|
55501
|
-
|
|
55502
|
-
|
|
55503
|
-
|
|
55504
|
-
|
|
55505
|
-
|
|
55506
|
-
|
|
55507
|
-
|
|
55529
|
+
const seen = /* @__PURE__ */ new Set();
|
|
55530
|
+
const unique = [];
|
|
55531
|
+
for (const t of tools) {
|
|
55532
|
+
if (seen.has(t.name))
|
|
55533
|
+
continue;
|
|
55534
|
+
seen.add(t.name);
|
|
55535
|
+
unique.push({
|
|
55536
|
+
type: "function",
|
|
55537
|
+
function: {
|
|
55538
|
+
name: t.name,
|
|
55539
|
+
description: t.description,
|
|
55540
|
+
parameters: t.inputSchema
|
|
55541
|
+
}
|
|
55542
|
+
});
|
|
55543
|
+
}
|
|
55544
|
+
return unique;
|
|
55508
55545
|
}
|
|
55509
55546
|
async chatStream(request, onEvent, signal) {
|
|
55510
55547
|
const messages = this.convertMessages(request.messages);
|
|
@@ -55551,6 +55588,7 @@ var init_openai = __esm({
|
|
|
55551
55588
|
throw new Error(`OpenAI API error ${res.status}: ${errText}`);
|
|
55552
55589
|
}
|
|
55553
55590
|
let content = "";
|
|
55591
|
+
let reasoningContent = "";
|
|
55554
55592
|
const toolCalls = /* @__PURE__ */ new Map();
|
|
55555
55593
|
let finishReason = "end_turn";
|
|
55556
55594
|
let promptTokens = 0;
|
|
@@ -55576,9 +55614,10 @@ var init_openai = __esm({
|
|
|
55576
55614
|
try {
|
|
55577
55615
|
const chunk = JSON.parse(trimmed.slice(6));
|
|
55578
55616
|
const choice = chunk.choices?.[0];
|
|
55579
|
-
const
|
|
55580
|
-
if (
|
|
55581
|
-
|
|
55617
|
+
const deltaReasoning = choice?.delta?.reasoning_content ?? choice?.delta?.reasoning_details ?? choice?.delta?.thinking;
|
|
55618
|
+
if (deltaReasoning) {
|
|
55619
|
+
reasoningContent += deltaReasoning;
|
|
55620
|
+
onEvent({ type: "thinking_delta", thinking: deltaReasoning });
|
|
55582
55621
|
}
|
|
55583
55622
|
if (choice?.delta?.content) {
|
|
55584
55623
|
content += choice.delta.content;
|
|
@@ -55629,12 +55668,15 @@ var init_openai = __esm({
|
|
|
55629
55668
|
});
|
|
55630
55669
|
const usage = { inputTokens: promptTokens, outputTokens: completionTokens };
|
|
55631
55670
|
onEvent({ type: "message_end", usage, finishReason });
|
|
55632
|
-
|
|
55671
|
+
const streamResult = {
|
|
55633
55672
|
content,
|
|
55634
55673
|
toolCalls: resultToolCalls.length ? resultToolCalls : void 0,
|
|
55635
55674
|
usage,
|
|
55636
55675
|
finishReason
|
|
55637
55676
|
};
|
|
55677
|
+
if (reasoningContent)
|
|
55678
|
+
streamResult.reasoningContent = reasoningContent;
|
|
55679
|
+
return streamResult;
|
|
55638
55680
|
}
|
|
55639
55681
|
convertResponse(data) {
|
|
55640
55682
|
const choice = data.choices[0];
|
|
@@ -55651,7 +55693,7 @@ var init_openai = __esm({
|
|
|
55651
55693
|
tool_calls: "tool_use",
|
|
55652
55694
|
length: "max_tokens"
|
|
55653
55695
|
};
|
|
55654
|
-
|
|
55696
|
+
const result = {
|
|
55655
55697
|
content: typeof msg.content === "string" ? msg.content : "",
|
|
55656
55698
|
toolCalls: toolCalls?.length ? toolCalls : void 0,
|
|
55657
55699
|
usage: {
|
|
@@ -55660,6 +55702,9 @@ var init_openai = __esm({
|
|
|
55660
55702
|
},
|
|
55661
55703
|
finishReason: finishMap[choice.finish_reason] ?? "end_turn"
|
|
55662
55704
|
};
|
|
55705
|
+
if (msg.reasoning_content)
|
|
55706
|
+
result.reasoningContent = msg.reasoning_content;
|
|
55707
|
+
return result;
|
|
55663
55708
|
}
|
|
55664
55709
|
};
|
|
55665
55710
|
}
|
|
@@ -56393,7 +56438,7 @@ var init_oauth_manager = __esm({
|
|
|
56393
56438
|
const state = randomBytes2(16).toString("hex");
|
|
56394
56439
|
const port = config.callbackPort ?? 1455;
|
|
56395
56440
|
const redirectUri = `http://localhost:${port}/auth/callback`;
|
|
56396
|
-
const promise = new Promise((
|
|
56441
|
+
const promise = new Promise((resolve20, reject) => {
|
|
56397
56442
|
const pending = {
|
|
56398
56443
|
provider,
|
|
56399
56444
|
state,
|
|
@@ -56402,7 +56447,7 @@ var init_oauth_manager = __esm({
|
|
|
56402
56447
|
redirectUri,
|
|
56403
56448
|
resolve: (tokens) => {
|
|
56404
56449
|
const profile = this.profileStore.createOAuthProfile(provider, tokens, `${provider} (${tokens.accountId ?? "OAuth"})`);
|
|
56405
|
-
|
|
56450
|
+
resolve20(profile);
|
|
56406
56451
|
},
|
|
56407
56452
|
reject
|
|
56408
56453
|
};
|
|
@@ -56758,7 +56803,7 @@ var init_router = __esm({
|
|
|
56758
56803
|
*/
|
|
56759
56804
|
static isNonRetryableError(error) {
|
|
56760
56805
|
const msg = error instanceof Error ? error.message : String(error);
|
|
56761
|
-
return /\b(402|403
|
|
56806
|
+
return /\b(401|402|403)\b/.test(msg) || /insufficient balance/i.test(msg) || /not available in your region/i.test(msg) || /invalid.*api.*key/i.test(msg) || /authentication/i.test(msg) || /\b400\b.*invalid_request_error/i.test(msg) || /reasoning_content.*must be passed back/i.test(msg);
|
|
56762
56807
|
}
|
|
56763
56808
|
/** Detect rate-limit (429) errors which should use a shorter circuit breaker cooldown. */
|
|
56764
56809
|
static isRateLimitError(error) {
|
|
@@ -56971,14 +57016,25 @@ var init_router = __esm({
|
|
|
56971
57016
|
return "simple";
|
|
56972
57017
|
}
|
|
56973
57018
|
selectProvider(request, explicit) {
|
|
56974
|
-
if (explicit)
|
|
57019
|
+
if (explicit && this.isAvailable(explicit))
|
|
56975
57020
|
return explicit;
|
|
57021
|
+
if (explicit && this.disabledProviders.has(explicit)) {
|
|
57022
|
+
log36.warn(`Explicit provider ${explicit} is disabled \u2014 falling through to auto-select`);
|
|
57023
|
+
}
|
|
56976
57024
|
if (!this.autoSelect || this.providerTiers.length === 0) {
|
|
56977
57025
|
if (this.isAvailable(this.defaultProvider) && this.providers.has(this.defaultProvider)) {
|
|
56978
57026
|
return this.defaultProvider;
|
|
56979
57027
|
}
|
|
56980
57028
|
const healthy2 = [...this.providers.keys()].find((n) => this.isAvailable(n));
|
|
56981
|
-
|
|
57029
|
+
if (healthy2)
|
|
57030
|
+
return healthy2;
|
|
57031
|
+
const enabledAny2 = [...this.providers.keys()].find((n) => !this.disabledProviders.has(n));
|
|
57032
|
+
if (enabledAny2) {
|
|
57033
|
+
log36.warn(`All providers degraded \u2014 using enabled provider ${enabledAny2} as last resort`);
|
|
57034
|
+
return enabledAny2;
|
|
57035
|
+
}
|
|
57036
|
+
log36.warn("All providers disabled or degraded \u2014 using default as last resort");
|
|
57037
|
+
return this.defaultProvider;
|
|
56982
57038
|
}
|
|
56983
57039
|
const complexity = _LLMRouter.assessComplexity(request);
|
|
56984
57040
|
const match = this.providerTiers.find((t) => t.complexity.includes(complexity) && this.providers.has(t.name) && this.isAvailable(t.name));
|
|
@@ -56991,7 +57047,12 @@ var init_router = __esm({
|
|
|
56991
57047
|
log36.warn(`All tiered providers degraded for complexity=${complexity}, falling back to: ${healthy}`);
|
|
56992
57048
|
return healthy;
|
|
56993
57049
|
}
|
|
56994
|
-
|
|
57050
|
+
const enabledAny = [...this.providers.keys()].find((n) => !this.disabledProviders.has(n));
|
|
57051
|
+
if (enabledAny) {
|
|
57052
|
+
log36.warn(`All providers degraded \u2014 using enabled provider ${enabledAny} as last resort`);
|
|
57053
|
+
return enabledAny;
|
|
57054
|
+
}
|
|
57055
|
+
log36.warn("All providers disabled or degraded \u2014 using default as last resort");
|
|
56995
57056
|
return this.defaultProvider;
|
|
56996
57057
|
}
|
|
56997
57058
|
getFallbacks(primary) {
|
|
@@ -57280,7 +57341,7 @@ var init_router = __esm({
|
|
|
57280
57341
|
for (const [name, p] of this.providers.entries()) {
|
|
57281
57342
|
providers[name] = { model: p.model, configured: true };
|
|
57282
57343
|
}
|
|
57283
|
-
for (const name of ["anthropic", "openai", "openai-codex", "google", "ollama", "minimax", "siliconflow", "openrouter", "zai"]) {
|
|
57344
|
+
for (const name of ["anthropic", "openai", "openai-codex", "google", "ollama", "minimax", "siliconflow", "openrouter", "zai", "deepseek"]) {
|
|
57284
57345
|
if (!providers[name]) {
|
|
57285
57346
|
providers[name] = { model: "", configured: false };
|
|
57286
57347
|
}
|
|
@@ -57312,7 +57373,7 @@ var init_router = __esm({
|
|
|
57312
57373
|
oauthAccountId: oauthProfile?.oauth?.accountId
|
|
57313
57374
|
};
|
|
57314
57375
|
}
|
|
57315
|
-
for (const name of ["anthropic", "openai", "openai-codex", "google", "ollama", "minimax", "siliconflow", "openrouter", "zai"]) {
|
|
57376
|
+
for (const name of ["anthropic", "openai", "openai-codex", "google", "ollama", "minimax", "siliconflow", "openrouter", "zai", "deepseek"]) {
|
|
57316
57377
|
if (!providers[name]) {
|
|
57317
57378
|
const oauthProfile = this._profileStore?.getDefaultProfile(name);
|
|
57318
57379
|
const builtinModels = BUILTIN_MODEL_CATALOG.filter((m) => m.provider === name);
|
|
@@ -57367,6 +57428,13 @@ var init_router = __esm({
|
|
|
57367
57428
|
this.disabledProviders.delete(providerName);
|
|
57368
57429
|
} else {
|
|
57369
57430
|
this.disabledProviders.add(providerName);
|
|
57431
|
+
if (this.defaultProvider === providerName) {
|
|
57432
|
+
const replacement = [...this.providers.keys()].find((n) => !this.disabledProviders.has(n));
|
|
57433
|
+
if (replacement) {
|
|
57434
|
+
log36.info(`Default provider ${providerName} disabled \u2014 switching default to ${replacement}`);
|
|
57435
|
+
this.defaultProvider = replacement;
|
|
57436
|
+
}
|
|
57437
|
+
}
|
|
57370
57438
|
}
|
|
57371
57439
|
log36.info(`Provider ${providerName} ${enabled ? "enabled" : "disabled"}`);
|
|
57372
57440
|
}
|
|
@@ -57479,7 +57547,8 @@ var init_router = __esm({
|
|
|
57479
57547
|
siliconflow: "SiliconFlow",
|
|
57480
57548
|
minimax: "MiniMax",
|
|
57481
57549
|
openrouter: "OpenRouter",
|
|
57482
|
-
zai: "ZAI"
|
|
57550
|
+
zai: "ZAI",
|
|
57551
|
+
deepseek: "DeepSeek"
|
|
57483
57552
|
};
|
|
57484
57553
|
BUILTIN_MODEL_CATALOG = [
|
|
57485
57554
|
// Anthropic — https://docs.anthropic.com/claude/reference/input-and-output-sizes
|
|
@@ -57503,7 +57572,12 @@ var init_router = __esm({
|
|
|
57503
57572
|
{ id: "xiaomi/mimo-v2-pro", name: "MiMo-V2-Pro", provider: "openrouter", contextWindow: 1048576, maxOutputTokens: 131072, cost: { input: 1, output: 3, cacheRead: 0.2 }, reasoning: true, inputTypes: ["text"] },
|
|
57504
57573
|
{ id: "anthropic/claude-opus-4-6", name: "Claude Opus 4.6 (via OpenRouter)", provider: "openrouter", contextWindow: 1e6, maxOutputTokens: 128e3, cost: { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 }, reasoning: true, inputTypes: ["text", "image"] },
|
|
57505
57574
|
{ id: "openai/gpt-5.4", name: "GPT-5.4 (via OpenRouter)", provider: "openrouter", contextWindow: 11e5, maxOutputTokens: 128e3, cost: { input: 2.5, output: 15, cacheRead: 0.25 }, reasoning: true, inputTypes: ["text", "image"] },
|
|
57506
|
-
{ id: "google/gemini-3-1-pro", name: "Gemini 3.1 Pro (via OpenRouter)", provider: "openrouter", contextWindow: 1e6, maxOutputTokens: 65536, cost: { input: 2, output: 12 }, reasoning: true, inputTypes: ["text", "image"] }
|
|
57575
|
+
{ id: "google/gemini-3-1-pro", name: "Gemini 3.1 Pro (via OpenRouter)", provider: "openrouter", contextWindow: 1e6, maxOutputTokens: 65536, cost: { input: 2, output: 12 }, reasoning: true, inputTypes: ["text", "image"] },
|
|
57576
|
+
// DeepSeek — https://api-docs.deepseek.com/
|
|
57577
|
+
{ id: "deepseek-v4-flash", name: "DeepSeek-V4-Flash", provider: "deepseek", contextWindow: 1e6, maxOutputTokens: 384e3, cost: { input: 0.14, output: 0.28, cacheRead: 0.028 }, reasoning: true, inputTypes: ["text"] },
|
|
57578
|
+
{ id: "deepseek-v4-pro", name: "DeepSeek-V4-Pro", provider: "deepseek", contextWindow: 1e6, maxOutputTokens: 384e3, cost: { input: 1.67, output: 3.33, cacheRead: 0.14 }, reasoning: true, inputTypes: ["text"] },
|
|
57579
|
+
{ id: "deepseek-chat", name: "DeepSeek-Chat (legacy)", provider: "deepseek", contextWindow: 65536, maxOutputTokens: 8192, cost: { input: 0.14, output: 0.28, cacheRead: 0.028 }, reasoning: false, inputTypes: ["text"] },
|
|
57580
|
+
{ id: "deepseek-reasoner", name: "DeepSeek-Reasoner (legacy)", provider: "deepseek", contextWindow: 65536, maxOutputTokens: 8192, cost: { input: 0.55, output: 2.19, cacheRead: 0.14 }, reasoning: true, inputTypes: ["text"] }
|
|
57507
57581
|
];
|
|
57508
57582
|
}
|
|
57509
57583
|
});
|
|
@@ -58364,7 +58438,7 @@ var init_registry = __esm({
|
|
|
58364
58438
|
|
|
58365
58439
|
// ../core/dist/skills/loader.js
|
|
58366
58440
|
import { readFileSync as readFileSync15, readdirSync as readdirSync5, existsSync as existsSync20 } from "node:fs";
|
|
58367
|
-
import { join as join16, resolve as
|
|
58441
|
+
import { join as join16, resolve as resolve9 } from "node:path";
|
|
58368
58442
|
function resolveMcpServerPaths(servers, skillDir) {
|
|
58369
58443
|
if (!servers)
|
|
58370
58444
|
return void 0;
|
|
@@ -59330,7 +59404,7 @@ var init_composition = __esm({
|
|
|
59330
59404
|
|
|
59331
59405
|
// ../core/dist/workflow/team-template.js
|
|
59332
59406
|
import { readdirSync as readdirSync7, readFileSync as readFileSync17, existsSync as existsSync22 } from "node:fs";
|
|
59333
|
-
import { join as join18, resolve as
|
|
59407
|
+
import { join as join18, resolve as resolve10, dirname as dirname5 } from "node:path";
|
|
59334
59408
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
59335
59409
|
function loadTeamTemplateFromDir(dirPath) {
|
|
59336
59410
|
const fsHelper = { existsSync: existsSync22, readFileSync: (p, _enc) => readFileSync17(p, "utf-8"), join: join18 };
|
|
@@ -59371,16 +59445,16 @@ function createDefaultTeamTemplates() {
|
|
|
59371
59445
|
const thisFile = fileURLToPath3(import.meta.url);
|
|
59372
59446
|
const thisDir = dirname5(thisFile);
|
|
59373
59447
|
const candidates = [
|
|
59374
|
-
|
|
59448
|
+
resolve10(thisDir, "..", "templates", "teams"),
|
|
59375
59449
|
// npm global: dist/ → ../templates/teams
|
|
59376
|
-
|
|
59450
|
+
resolve10(thisDir, "..", "..", "..", "..", "templates", "teams"),
|
|
59377
59451
|
// monorepo: packages/core/dist/workflow/ → root
|
|
59378
|
-
|
|
59452
|
+
resolve10(process.cwd(), "templates", "teams")
|
|
59379
59453
|
// cwd fallback
|
|
59380
59454
|
];
|
|
59381
59455
|
templatesDir = candidates.find((d) => existsSync22(d)) ?? candidates[candidates.length - 1];
|
|
59382
59456
|
} catch {
|
|
59383
|
-
templatesDir =
|
|
59457
|
+
templatesDir = resolve10(process.cwd(), "templates", "teams");
|
|
59384
59458
|
}
|
|
59385
59459
|
if (!existsSync22(templatesDir)) {
|
|
59386
59460
|
log47.warn(`Team templates directory not found: ${templatesDir}`);
|
|
@@ -60405,7 +60479,7 @@ var init_org_service = __esm({
|
|
|
60405
60479
|
|
|
60406
60480
|
// ../org-manager/dist/task-service.js
|
|
60407
60481
|
import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync14, readFileSync as readFileSync18, existsSync as existsSync24, cpSync } from "node:fs";
|
|
60408
|
-
import { join as join20, resolve as
|
|
60482
|
+
import { join as join20, resolve as resolve11 } from "node:path";
|
|
60409
60483
|
import { homedir as homedir11 } from "node:os";
|
|
60410
60484
|
function formatLocalTimestamp(d = /* @__PURE__ */ new Date()) {
|
|
60411
60485
|
const pad = (n) => String(n).padStart(2, "0");
|
|
@@ -60806,6 +60880,10 @@ var init_task_service = __esm({
|
|
|
60806
60880
|
const lower = errorContent.toLowerCase();
|
|
60807
60881
|
return lower.includes("econnreset") || lower.includes("econnrefused") || lower.includes("etimedout") || lower.includes("fetch failed") || lower.includes("aborterror") || lower.includes("aborted") || lower.includes("socket hang up") || lower.includes("network");
|
|
60808
60882
|
}
|
|
60883
|
+
static isNonRetryableError(errorContent) {
|
|
60884
|
+
const lower = errorContent.toLowerCase();
|
|
60885
|
+
return lower.includes("invalid_request_error") && /\b400\b/.test(errorContent) || lower.includes("reasoning_content") || lower.includes("invalid api key") || lower.includes("insufficient balance") || /\b(401|402|403)\b/.test(errorContent) && !lower.includes("rate");
|
|
60886
|
+
}
|
|
60809
60887
|
shouldRetryTask(taskId2, errorContent, retryAttempt, cancelled) {
|
|
60810
60888
|
if (cancelled)
|
|
60811
60889
|
return { shouldRetry: false, reason: "cancelled" };
|
|
@@ -60816,6 +60894,9 @@ var init_task_service = __esm({
|
|
|
60816
60894
|
if (retryAttempt >= _TaskService.MAX_IN_PROGRESS_RETRIES) {
|
|
60817
60895
|
return { shouldRetry: false, reason: `exceeded max retries (${_TaskService.MAX_IN_PROGRESS_RETRIES})` };
|
|
60818
60896
|
}
|
|
60897
|
+
if (_TaskService.isNonRetryableError(errorContent)) {
|
|
60898
|
+
return { shouldRetry: false, reason: "non-retryable error (auth/billing/request)" };
|
|
60899
|
+
}
|
|
60819
60900
|
const normalizedError = errorContent.replace(/\d{4}-\d{2}-\d{2}T[\d:.]+Z?/g, "").trim().slice(0, 200);
|
|
60820
60901
|
const tracker = this.taskRetryErrors.get(taskId2);
|
|
60821
60902
|
if (tracker && tracker.lastError === normalizedError) {
|
|
@@ -61785,7 +61866,7 @@ ${c.content}`;
|
|
|
61785
61866
|
});
|
|
61786
61867
|
if (this.hitlService && request.createdBy && request.createdBy !== "default") {
|
|
61787
61868
|
this.hitlService.notify({
|
|
61788
|
-
targetUserId: "
|
|
61869
|
+
targetUserId: "all",
|
|
61789
61870
|
type: "task_created",
|
|
61790
61871
|
title: `Task created: ${task.title}`,
|
|
61791
61872
|
body: `Agent created task "${task.title}"`,
|
|
@@ -62052,7 +62133,7 @@ Action: ${guidance}` : ""
|
|
|
62052
62133
|
const notifType = to === "completed" ? "task_completed" : to === "review" ? "task_review" : "task_failed";
|
|
62053
62134
|
const priority = to === "failed" ? "high" : "normal";
|
|
62054
62135
|
this.hitlService.notify({
|
|
62055
|
-
targetUserId: "
|
|
62136
|
+
targetUserId: "all",
|
|
62056
62137
|
type: notifType,
|
|
62057
62138
|
title: to === "review" ? `Task ready for review: ${task.title}` : to === "completed" ? `Task completed: ${task.title}` : `Task failed: ${task.title}`,
|
|
62058
62139
|
body: `Task "${task.title}" status changed to ${to}`,
|
|
@@ -62825,8 +62906,9 @@ Action: ${guidance}` : ""
|
|
|
62825
62906
|
};
|
|
62826
62907
|
writeFileSync14(join20(taskSharedDir, "manifest.json"), JSON.stringify(manifest, null, 2));
|
|
62827
62908
|
for (const d of deliverables) {
|
|
62909
|
+
let src;
|
|
62828
62910
|
if (d.type === "file" && d.reference) {
|
|
62829
|
-
|
|
62911
|
+
src = resolve11(d.reference);
|
|
62830
62912
|
if (existsSync24(src)) {
|
|
62831
62913
|
try {
|
|
62832
62914
|
const destName = src.split("/").pop() ?? "deliverable";
|
|
@@ -62836,8 +62918,9 @@ Action: ${guidance}` : ""
|
|
|
62836
62918
|
}
|
|
62837
62919
|
}
|
|
62838
62920
|
}
|
|
62839
|
-
if (d.type === "file" && d.summary && !existsSync24(
|
|
62840
|
-
const
|
|
62921
|
+
if (d.type === "file" && d.summary && src && !existsSync24(src)) {
|
|
62922
|
+
const baseName = d.reference.split("/").pop() ?? "deliverable";
|
|
62923
|
+
const safeName = baseName.replace(/[^a-zA-Z0-9_\u4e00-\u9fff.-]/g, "_").slice(0, 80);
|
|
62841
62924
|
writeFileSync14(join20(taskSharedDir, `${safeName}.md`), d.summary);
|
|
62842
62925
|
}
|
|
62843
62926
|
}
|
|
@@ -64619,7 +64702,7 @@ var init_sse_handler = __esm({
|
|
|
64619
64702
|
});
|
|
64620
64703
|
|
|
64621
64704
|
// ../org-manager/dist/skill-service.js
|
|
64622
|
-
import { join as join22, resolve as
|
|
64705
|
+
import { join as join22, resolve as resolve12 } from "node:path";
|
|
64623
64706
|
import { existsSync as existsSync26, writeFileSync as writeFileSync16, mkdirSync as mkdirSync18, readFileSync as readFileSync20, readdirSync as readdirSync9, copyFileSync as copyFileSync3 } from "node:fs";
|
|
64624
64707
|
import { homedir as homedir13 } from "node:os";
|
|
64625
64708
|
import { execSync as execSync2 } from "node:child_process";
|
|
@@ -64754,7 +64837,7 @@ async function installSkill(request, skillRegistry) {
|
|
|
64754
64837
|
let installed = false;
|
|
64755
64838
|
let installMethod = "metadata-only";
|
|
64756
64839
|
if (source === "builtin") {
|
|
64757
|
-
const builtinDir =
|
|
64840
|
+
const builtinDir = resolve12(process.cwd(), "templates", "skills", safeName);
|
|
64758
64841
|
if (existsSync26(builtinDir)) {
|
|
64759
64842
|
mkdirSync18(targetDir, { recursive: true });
|
|
64760
64843
|
for (const file of readdirSync9(builtinDir)) {
|
|
@@ -64898,7 +64981,7 @@ var init_skill_service = __esm({
|
|
|
64898
64981
|
|
|
64899
64982
|
// ../org-manager/dist/api-server.js
|
|
64900
64983
|
import { createServer as createServer2 } from "node:http";
|
|
64901
|
-
import { join as join23, resolve as
|
|
64984
|
+
import { join as join23, resolve as resolve13, dirname as dirname6 } from "node:path";
|
|
64902
64985
|
import { readdirSync as readdirSync10, readFileSync as readFileSync21, existsSync as existsSync27, writeFileSync as writeFileSync17, mkdirSync as mkdirSync19, rmSync as rmSync3, statSync as statSync5 } from "node:fs";
|
|
64903
64986
|
import { homedir as homedir14 } from "node:os";
|
|
64904
64987
|
import { execSync as execSync3 } from "node:child_process";
|
|
@@ -68687,7 +68770,7 @@ EXPLANATION_END`;
|
|
|
68687
68770
|
return;
|
|
68688
68771
|
}
|
|
68689
68772
|
if (path === "/api/skills/builtin" && req.method === "GET") {
|
|
68690
|
-
const builtinDir =
|
|
68773
|
+
const builtinDir = resolve13(process.cwd(), "templates", "skills");
|
|
68691
68774
|
const found = discoverSkillsInDir(builtinDir);
|
|
68692
68775
|
const installedSkills = new Map((this.skillRegistry?.list() ?? []).map((s) => [s.name, s]));
|
|
68693
68776
|
const skills = found.map(({ manifest, path: p }) => {
|
|
@@ -69756,10 +69839,10 @@ EXPLANATION_END`;
|
|
|
69756
69839
|
if (path === "/api/templates/teams" && req.method === "GET") {
|
|
69757
69840
|
try {
|
|
69758
69841
|
const { readdirSync: readdirSync13, readFileSync: readFileSync27 } = await import("node:fs");
|
|
69759
|
-
const { resolve:
|
|
69760
|
-
const teamsDir =
|
|
69842
|
+
const { resolve: resolve20 } = await import("node:path");
|
|
69843
|
+
const teamsDir = resolve20(process.cwd(), "templates", "teams");
|
|
69761
69844
|
const files = readdirSync13(teamsDir).filter((f) => f.endsWith(".json"));
|
|
69762
|
-
const teams = files.map((f) => JSON.parse(readFileSync27(
|
|
69845
|
+
const teams = files.map((f) => JSON.parse(readFileSync27(resolve20(teamsDir, f), "utf-8")));
|
|
69763
69846
|
this.json(res, 200, { templates: teams });
|
|
69764
69847
|
} catch {
|
|
69765
69848
|
this.json(res, 200, { templates: [] });
|
|
@@ -70310,7 +70393,9 @@ EXPLANATION_END`;
|
|
|
70310
70393
|
return;
|
|
70311
70394
|
}
|
|
70312
70395
|
try {
|
|
70396
|
+
const prevDefault = this.llmRouter.getSettings().defaultProvider;
|
|
70313
70397
|
this.llmRouter.setProviderEnabled(providerName, enabled);
|
|
70398
|
+
const newDefault = this.llmRouter.getSettings().defaultProvider;
|
|
70314
70399
|
try {
|
|
70315
70400
|
const { loadConfig: loadCfg } = await Promise.resolve().then(() => (init_dist(), dist_exports));
|
|
70316
70401
|
const currentConfig = loadCfg(this.markusConfigPath);
|
|
@@ -70320,7 +70405,11 @@ EXPLANATION_END`;
|
|
|
70320
70405
|
} else {
|
|
70321
70406
|
providers[providerName] = { enabled };
|
|
70322
70407
|
}
|
|
70323
|
-
|
|
70408
|
+
const configUpdates = { llm: { providers } };
|
|
70409
|
+
if (prevDefault !== newDefault) {
|
|
70410
|
+
configUpdates.llm.defaultProvider = newDefault;
|
|
70411
|
+
}
|
|
70412
|
+
saveConfig(configUpdates, this.markusConfigPath);
|
|
70324
70413
|
} catch (e) {
|
|
70325
70414
|
log57.warn("Failed to persist provider enabled state", { error: String(e) });
|
|
70326
70415
|
}
|
|
@@ -70330,6 +70419,70 @@ EXPLANATION_END`;
|
|
|
70330
70419
|
}
|
|
70331
70420
|
return;
|
|
70332
70421
|
}
|
|
70422
|
+
if (path.match(/^\/api\/settings\/llm\/providers\/[^/]+\/test$/) && req.method === "POST") {
|
|
70423
|
+
const auth = await this.requireAuth(req, res);
|
|
70424
|
+
if (!auth)
|
|
70425
|
+
return;
|
|
70426
|
+
if (!this.llmRouter) {
|
|
70427
|
+
this.json(res, 503, { error: "LLM router not available" });
|
|
70428
|
+
return;
|
|
70429
|
+
}
|
|
70430
|
+
const providerName = path.split("/")[5];
|
|
70431
|
+
const provider = this.llmRouter.getProvider(providerName);
|
|
70432
|
+
if (!provider) {
|
|
70433
|
+
this.json(res, 404, { ok: false, error: `Provider "${providerName}" not found or not configured` });
|
|
70434
|
+
return;
|
|
70435
|
+
}
|
|
70436
|
+
try {
|
|
70437
|
+
const startMs = Date.now();
|
|
70438
|
+
const response = await this.llmRouter.chat({
|
|
70439
|
+
messages: [{ role: "user", content: "Reply with exactly one word: hello" }],
|
|
70440
|
+
maxTokens: 32,
|
|
70441
|
+
temperature: 0
|
|
70442
|
+
}, providerName);
|
|
70443
|
+
const durationMs = Date.now() - startMs;
|
|
70444
|
+
const reply = (response.content ?? "").trim();
|
|
70445
|
+
if (!reply) {
|
|
70446
|
+
this.json(res, 200, {
|
|
70447
|
+
ok: false,
|
|
70448
|
+
error: "Model returned empty response \u2014 API key or model may be misconfigured",
|
|
70449
|
+
model: provider.model,
|
|
70450
|
+
durationMs
|
|
70451
|
+
});
|
|
70452
|
+
} else {
|
|
70453
|
+
this.json(res, 200, {
|
|
70454
|
+
ok: true,
|
|
70455
|
+
durationMs,
|
|
70456
|
+
model: provider.model,
|
|
70457
|
+
reply: reply.slice(0, 100),
|
|
70458
|
+
usage: response.usage
|
|
70459
|
+
});
|
|
70460
|
+
}
|
|
70461
|
+
} catch (err) {
|
|
70462
|
+
const raw = String(err);
|
|
70463
|
+
const statusMatch = raw.match(/(?:API error|status)\s+(\d{3})/i);
|
|
70464
|
+
const errorCode = statusMatch ? Number(statusMatch[1]) : void 0;
|
|
70465
|
+
let errorMsg = raw.replace(/^Error:\s*/, "");
|
|
70466
|
+
const jsonStart = errorMsg.indexOf("{");
|
|
70467
|
+
if (jsonStart >= 0) {
|
|
70468
|
+
try {
|
|
70469
|
+
const jsonStr = errorMsg.slice(jsonStart);
|
|
70470
|
+
const parsed = JSON.parse(jsonStr);
|
|
70471
|
+
if (parsed.error?.message) {
|
|
70472
|
+
errorMsg = `[${parsed.error.type ?? parsed.error.code ?? errorCode ?? "error"}] ${parsed.error.message}`;
|
|
70473
|
+
}
|
|
70474
|
+
} catch {
|
|
70475
|
+
}
|
|
70476
|
+
}
|
|
70477
|
+
this.json(res, 200, {
|
|
70478
|
+
ok: false,
|
|
70479
|
+
error: errorMsg.slice(0, 500),
|
|
70480
|
+
errorCode,
|
|
70481
|
+
model: provider.model
|
|
70482
|
+
});
|
|
70483
|
+
}
|
|
70484
|
+
return;
|
|
70485
|
+
}
|
|
70333
70486
|
if (path === "/api/settings/env-models" && req.method === "GET") {
|
|
70334
70487
|
const auth = await this.requireAuth(req, res);
|
|
70335
70488
|
if (!auth)
|
|
@@ -70341,7 +70494,8 @@ EXPLANATION_END`;
|
|
|
70341
70494
|
{ provider: "siliconflow", displayName: "SiliconFlow", keyEnv: "SILICONFLOW_API_KEY", modelEnv: "SILICONFLOW_MODEL", baseUrlEnv: "SILICONFLOW_BASE_URL", defaultModel: "Qwen/Qwen3.5-35B-A3B", defaultBaseUrl: "https://api.siliconflow.cn/v1" },
|
|
70342
70495
|
{ provider: "minimax", displayName: "MiniMax", keyEnv: "MINIMAX_API_KEY", modelEnv: "MINIMAX_MODEL", baseUrlEnv: "MINIMAX_BASE_URL", defaultModel: "MiniMax-M2.7", defaultBaseUrl: "https://api.minimax.io/v1" },
|
|
70343
70496
|
{ provider: "openrouter", displayName: "OpenRouter", keyEnv: "OPENROUTER_API_KEY", modelEnv: "OPENROUTER_MODEL", baseUrlEnv: "OPENROUTER_BASE_URL", defaultModel: "xiaomi/mimo-v2-pro", defaultBaseUrl: "https://openrouter.ai/api/v1" },
|
|
70344
|
-
{ provider: "zai", displayName: "ZAI", keyEnv: "ZAI_API_KEY", modelEnv: "ZAI_MODEL", baseUrlEnv: "ZAI_BASE_URL", defaultModel: "glm-5.1", defaultBaseUrl: "https://api.z.ai/api/paas/v4" }
|
|
70497
|
+
{ provider: "zai", displayName: "ZAI", keyEnv: "ZAI_API_KEY", modelEnv: "ZAI_MODEL", baseUrlEnv: "ZAI_BASE_URL", defaultModel: "glm-5.1", defaultBaseUrl: "https://api.z.ai/api/paas/v4" },
|
|
70498
|
+
{ provider: "deepseek", displayName: "DeepSeek", keyEnv: "DEEPSEEK_API_KEY", modelEnv: "DEEPSEEK_MODEL", baseUrlEnv: "DEEPSEEK_BASE_URL", defaultModel: "deepseek-v4-flash", defaultBaseUrl: "https://api.deepseek.com" }
|
|
70345
70499
|
];
|
|
70346
70500
|
const detected = [];
|
|
70347
70501
|
for (const def of ENV_MODEL_MAP) {
|
|
@@ -70394,7 +70548,9 @@ EXPLANATION_END`;
|
|
|
70394
70548
|
google: "GOOGLE_API_KEY",
|
|
70395
70549
|
siliconflow: "SILICONFLOW_API_KEY",
|
|
70396
70550
|
minimax: "MINIMAX_API_KEY",
|
|
70397
|
-
openrouter: "OPENROUTER_API_KEY"
|
|
70551
|
+
openrouter: "OPENROUTER_API_KEY",
|
|
70552
|
+
zai: "ZAI_API_KEY",
|
|
70553
|
+
deepseek: "DEEPSEEK_API_KEY"
|
|
70398
70554
|
};
|
|
70399
70555
|
const apiKey = process.env[envKeyMap[pu.provider] ?? ""];
|
|
70400
70556
|
if (!apiKey)
|
|
@@ -71013,14 +71169,14 @@ EXPLANATION_END`;
|
|
|
71013
71169
|
return;
|
|
71014
71170
|
}
|
|
71015
71171
|
try {
|
|
71016
|
-
const { resolve:
|
|
71172
|
+
const { resolve: resolve20, extname } = await import("node:path");
|
|
71017
71173
|
const { existsSync: existsSync36, statSync: statSync6 } = await import("node:fs");
|
|
71018
71174
|
const results = {};
|
|
71019
71175
|
const mdExts = [".md", ".markdown"];
|
|
71020
71176
|
const imageExts = [".png", ".jpg", ".jpeg", ".gif", ".webp", ".svg"];
|
|
71021
71177
|
for (const p of paths.slice(0, 50)) {
|
|
71022
71178
|
try {
|
|
71023
|
-
const resolved =
|
|
71179
|
+
const resolved = resolve20(p);
|
|
71024
71180
|
if (!existsSync36(resolved)) {
|
|
71025
71181
|
results[p] = { exists: false, isFile: false, type: "unknown" };
|
|
71026
71182
|
continue;
|
|
@@ -71053,9 +71209,9 @@ EXPLANATION_END`;
|
|
|
71053
71209
|
return;
|
|
71054
71210
|
}
|
|
71055
71211
|
try {
|
|
71056
|
-
const { resolve:
|
|
71212
|
+
const { resolve: resolve20, extname } = await import("node:path");
|
|
71057
71213
|
const { readFileSync: readFileSync27, existsSync: existsSync36, statSync: statSync6 } = await import("node:fs");
|
|
71058
|
-
const resolved =
|
|
71214
|
+
const resolved = resolve20(filePath);
|
|
71059
71215
|
if (!existsSync36(resolved)) {
|
|
71060
71216
|
this.json(res, 404, { error: "File not found" });
|
|
71061
71217
|
return;
|
|
@@ -71103,10 +71259,10 @@ EXPLANATION_END`;
|
|
|
71103
71259
|
return;
|
|
71104
71260
|
}
|
|
71105
71261
|
try {
|
|
71106
|
-
const { resolve:
|
|
71262
|
+
const { resolve: resolve20, dirname: dirname11 } = await import("node:path");
|
|
71107
71263
|
const { existsSync: existsSync36, statSync: statSync6 } = await import("node:fs");
|
|
71108
71264
|
const { exec: exec2 } = await import("node:child_process");
|
|
71109
|
-
const resolved =
|
|
71265
|
+
const resolved = resolve20(filePath);
|
|
71110
71266
|
if (!existsSync36(resolved)) {
|
|
71111
71267
|
this.json(res, 404, { error: "Path not found" });
|
|
71112
71268
|
return;
|
|
@@ -71836,14 +71992,14 @@ EXPLANATION_END`;
|
|
|
71836
71992
|
res.end(JSON.stringify(data));
|
|
71837
71993
|
}
|
|
71838
71994
|
readBody(req) {
|
|
71839
|
-
return new Promise((
|
|
71995
|
+
return new Promise((resolve20, reject) => {
|
|
71840
71996
|
const chunks = [];
|
|
71841
71997
|
req.on("data", (chunk) => chunks.push(chunk));
|
|
71842
71998
|
req.on("end", () => {
|
|
71843
71999
|
try {
|
|
71844
|
-
|
|
72000
|
+
resolve20(JSON.parse(Buffer.concat(chunks).toString()));
|
|
71845
72001
|
} catch {
|
|
71846
|
-
|
|
72002
|
+
resolve20({});
|
|
71847
72003
|
}
|
|
71848
72004
|
});
|
|
71849
72005
|
req.on("error", reject);
|
|
@@ -72153,7 +72309,7 @@ var init_hitl_service = __esm({
|
|
|
72153
72309
|
this.persistApproval(approval);
|
|
72154
72310
|
log58.info(`Approval requested: ${id} by ${opts.agentName}`);
|
|
72155
72311
|
this.notify({
|
|
72156
|
-
targetUserId: opts.targetUserId ?? "
|
|
72312
|
+
targetUserId: opts.targetUserId ?? "all",
|
|
72157
72313
|
type: "approval_request",
|
|
72158
72314
|
title: `Approval needed: ${opts.title}`,
|
|
72159
72315
|
body: opts.description,
|
|
@@ -72166,13 +72322,13 @@ var init_hitl_service = __esm({
|
|
|
72166
72322
|
}
|
|
72167
72323
|
async requestApprovalAndWait(opts) {
|
|
72168
72324
|
const approval = this.requestApproval(opts);
|
|
72169
|
-
return new Promise((
|
|
72170
|
-
this.pendingResolvers.set(approval.id,
|
|
72325
|
+
return new Promise((resolve20) => {
|
|
72326
|
+
this.pendingResolvers.set(approval.id, resolve20);
|
|
72171
72327
|
if (opts.expiresInMs) {
|
|
72172
72328
|
setTimeout(() => {
|
|
72173
72329
|
if (this.pendingResolvers.has(approval.id)) {
|
|
72174
72330
|
this.pendingResolvers.delete(approval.id);
|
|
72175
|
-
|
|
72331
|
+
resolve20({ approved: false, comment: "Approval timed out" });
|
|
72176
72332
|
}
|
|
72177
72333
|
}, opts.expiresInMs);
|
|
72178
72334
|
}
|
|
@@ -72202,10 +72358,10 @@ var init_hitl_service = __esm({
|
|
|
72202
72358
|
} catch {
|
|
72203
72359
|
}
|
|
72204
72360
|
}
|
|
72205
|
-
const
|
|
72206
|
-
if (
|
|
72361
|
+
const resolve20 = this.pendingResolvers.get(id);
|
|
72362
|
+
if (resolve20) {
|
|
72207
72363
|
this.pendingResolvers.delete(id);
|
|
72208
|
-
|
|
72364
|
+
resolve20({ approved, comment, selectedOption });
|
|
72209
72365
|
}
|
|
72210
72366
|
return approval;
|
|
72211
72367
|
}
|
|
@@ -72921,7 +73077,7 @@ var init_requirement_service = __esm({
|
|
|
72921
73077
|
title: `Requirement approval: ${req.title}`,
|
|
72922
73078
|
description: `Agent "${req.createdBy}" proposed requirement "${req.title}" (priority: ${req.priority}).`,
|
|
72923
73079
|
details: { requirementId: req.id, priority: req.priority },
|
|
72924
|
-
targetUserId: "
|
|
73080
|
+
targetUserId: "all"
|
|
72925
73081
|
}).then((result) => {
|
|
72926
73082
|
const current = this.requirements.get(req.id);
|
|
72927
73083
|
if (!current || current.status !== "pending")
|
|
@@ -73054,7 +73210,7 @@ var init_requirement_service = __esm({
|
|
|
73054
73210
|
title: `Requirement approval (resubmitted): ${req.title}`,
|
|
73055
73211
|
description: `Agent "${req.createdBy}" resubmitted requirement "${req.title}" (priority: ${req.priority}).`,
|
|
73056
73212
|
details: { requirementId: req.id, priority: req.priority },
|
|
73057
|
-
targetUserId: "
|
|
73213
|
+
targetUserId: "all"
|
|
73058
73214
|
}).then((result) => {
|
|
73059
73215
|
const current = this.requirements.get(req.id);
|
|
73060
73216
|
if (!current || current.status !== "pending")
|
|
@@ -73373,7 +73529,7 @@ var init_requirement_service = __esm({
|
|
|
73373
73529
|
const title = decision === "approved" ? `Requirement approved: ${req.title}` : `Requirement rejected: ${req.title}`;
|
|
73374
73530
|
const body = decision === "approved" ? `Requirement "${req.title}" has been approved and is now in progress.` : `Requirement "${req.title}" has been rejected.${reason ? ` Reason: ${reason}` : ""}`;
|
|
73375
73531
|
this.hitlService.notify({
|
|
73376
|
-
targetUserId: "
|
|
73532
|
+
targetUserId: "all",
|
|
73377
73533
|
type: "requirement_decision",
|
|
73378
73534
|
title,
|
|
73379
73535
|
body,
|
|
@@ -77197,8 +77353,8 @@ CREATE INDEX IF NOT EXISTS idx_group_chat_members_group ON group_chat_members(gr
|
|
|
77197
77353
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(n.id, n.userId, n.type, n.title, n.body, n.priority, n.read ? 1 : 0, n.actionType, n.actionTarget, n.metadata ? JSON.stringify(n.metadata) : null, n.createdAt);
|
|
77198
77354
|
}
|
|
77199
77355
|
list(userId, opts) {
|
|
77200
|
-
const conditions = ["(user_id = ? OR user_id = ?)"];
|
|
77201
|
-
const params = [userId, "all"];
|
|
77356
|
+
const conditions = ["(user_id = ? OR user_id = ? OR user_id = ?)"];
|
|
77357
|
+
const params = [userId, "all", "default"];
|
|
77202
77358
|
if (opts?.unreadOnly) {
|
|
77203
77359
|
conditions.push("read = 0");
|
|
77204
77360
|
}
|
|
@@ -77213,8 +77369,8 @@ CREATE INDEX IF NOT EXISTS idx_group_chat_members_group ON group_chat_members(gr
|
|
|
77213
77369
|
return this.db.prepare(sql).all(...params).map((r) => this.mapRow(r));
|
|
77214
77370
|
}
|
|
77215
77371
|
count(userId, unreadOnly = false) {
|
|
77216
|
-
const conditions = ["(user_id = ? OR user_id = ?)"];
|
|
77217
|
-
const params = [userId, "all"];
|
|
77372
|
+
const conditions = ["(user_id = ? OR user_id = ? OR user_id = ?)"];
|
|
77373
|
+
const params = [userId, "all", "default"];
|
|
77218
77374
|
if (unreadOnly)
|
|
77219
77375
|
conditions.push("read = 0");
|
|
77220
77376
|
const row = this.db.prepare(`SELECT COUNT(*) as cnt FROM user_notifications WHERE ${conditions.join(" AND ")}`).get(...params);
|
|
@@ -77225,7 +77381,7 @@ CREATE INDEX IF NOT EXISTS idx_group_chat_members_group ON group_chat_members(gr
|
|
|
77225
77381
|
return info4.changes > 0;
|
|
77226
77382
|
}
|
|
77227
77383
|
markAllRead(userId) {
|
|
77228
|
-
const info4 = this.db.prepare("UPDATE user_notifications SET read = 1 WHERE (user_id = ? OR user_id = ?) AND read = 0").run(userId, "all");
|
|
77384
|
+
const info4 = this.db.prepare("UPDATE user_notifications SET read = 1 WHERE (user_id = ? OR user_id = ? OR user_id = ?) AND read = 0").run(userId, "all", "default");
|
|
77229
77385
|
return Number(info4.changes);
|
|
77230
77386
|
}
|
|
77231
77387
|
mapRow(r) {
|
|
@@ -78563,7 +78719,7 @@ var init_startupProgress = __esm({
|
|
|
78563
78719
|
});
|
|
78564
78720
|
|
|
78565
78721
|
// src/connector-service.ts
|
|
78566
|
-
import { resolve as
|
|
78722
|
+
import { resolve as resolve14, join as join28, dirname as dirname8 } from "node:path";
|
|
78567
78723
|
import { existsSync as existsSync31, readFileSync as readFileSync23, writeFileSync as writeFileSync19, mkdirSync as mkdirSync24, readdirSync as readdirSync12, cpSync as cpSync3 } from "node:fs";
|
|
78568
78724
|
import { homedir as homedir18 } from "node:os";
|
|
78569
78725
|
import { execSync as execSync4 } from "node:child_process";
|
|
@@ -78573,9 +78729,9 @@ function expandHome(p) {
|
|
|
78573
78729
|
}
|
|
78574
78730
|
function loadConnectors() {
|
|
78575
78731
|
const connectors = /* @__PURE__ */ new Map();
|
|
78576
|
-
const builtinDir =
|
|
78732
|
+
const builtinDir = resolve14(__dirname3, "..", "connectors");
|
|
78577
78733
|
loadFromDir(builtinDir, connectors);
|
|
78578
|
-
const devDir =
|
|
78734
|
+
const devDir = resolve14(process.cwd(), "packages", "cli", "connectors");
|
|
78579
78735
|
if (devDir !== builtinDir) loadFromDir(devDir, connectors);
|
|
78580
78736
|
const userDir = join28(homedir18(), ".markus", "connectors");
|
|
78581
78737
|
loadFromDir(userDir, connectors);
|
|
@@ -78679,8 +78835,8 @@ function installSkillTemplate(connector) {
|
|
|
78679
78835
|
const templateName = connector.integration.skillTemplateName;
|
|
78680
78836
|
const candidates = [
|
|
78681
78837
|
join28(homedir18(), ".markus", "templates", templateName),
|
|
78682
|
-
|
|
78683
|
-
|
|
78838
|
+
resolve14(process.cwd(), "templates", templateName),
|
|
78839
|
+
resolve14(__dirname3, "..", "templates", templateName)
|
|
78684
78840
|
];
|
|
78685
78841
|
let sourceDir;
|
|
78686
78842
|
for (const c of candidates) {
|
|
@@ -78744,11 +78900,11 @@ __export(init_exports, {
|
|
|
78744
78900
|
quickInit: () => quickInit,
|
|
78745
78901
|
registerInitCommand: () => registerInitCommand
|
|
78746
78902
|
});
|
|
78747
|
-
import { resolve as
|
|
78903
|
+
import { resolve as resolve15 } from "node:path";
|
|
78748
78904
|
import { readFileSync as readFileSync24, existsSync as existsSync32, cpSync as cpSync4 } from "node:fs";
|
|
78749
78905
|
import { homedir as homedir19 } from "node:os";
|
|
78750
78906
|
function registerInitCommand(program2) {
|
|
78751
|
-
program2.command("init").description("Setup wizard: configure LLM provider, API keys, and server settings").option("--force", "Overwrite existing configuration").option("--non-interactive", "Run without prompts (use env vars or --import-from)").option("--provider <name>", "LLM provider (anthropic/openai/google/minimax/siliconflow/zai/ollama)").option("--api-key <key>", "LLM API key").option("--port <port>", "API server port", "8056").option("--import-from <platform>", "Import LLM config from an installed agent platform (e.g. openclaw, hermes)").option("--auto-connect", "Auto-connect detected agent platforms after init").action(async (opts) => {
|
|
78907
|
+
program2.command("init").description("Setup wizard: configure LLM provider, API keys, and server settings").option("--force", "Overwrite existing configuration").option("--non-interactive", "Run without prompts (use env vars or --import-from)").option("--provider <name>", "LLM provider (anthropic/openai/google/minimax/siliconflow/zai/deepseek/ollama)").option("--api-key <key>", "LLM API key").option("--port <port>", "API server port", "8056").option("--import-from <platform>", "Import LLM config from an installed agent platform (e.g. openclaw, hermes)").option("--auto-connect", "Auto-connect detected agent platforms after init").action(async (opts) => {
|
|
78752
78908
|
await quickInit({
|
|
78753
78909
|
force: opts.force,
|
|
78754
78910
|
nonInteractive: opts.nonInteractive,
|
|
@@ -78805,7 +78961,8 @@ async function quickInit(options) {
|
|
|
78805
78961
|
siliconflow: "Qwen/Qwen3.5-35B-A3B",
|
|
78806
78962
|
ollama: "llama3",
|
|
78807
78963
|
openrouter: "xiaomi/mimo-v2-pro",
|
|
78808
|
-
zai: "glm-5.1"
|
|
78964
|
+
zai: "glm-5.1",
|
|
78965
|
+
deepseek: "deepseek-v4-flash"
|
|
78809
78966
|
};
|
|
78810
78967
|
const ENV_KEY_MAP = [
|
|
78811
78968
|
{ provider: "anthropic", label: "Anthropic", envKey: "ANTHROPIC_API_KEY" },
|
|
@@ -78814,7 +78971,8 @@ async function quickInit(options) {
|
|
|
78814
78971
|
{ provider: "siliconflow", label: "SiliconFlow", envKey: "SILICONFLOW_API_KEY", baseUrl: "https://api.siliconflow.cn/v1" },
|
|
78815
78972
|
{ provider: "minimax", label: "MiniMax", envKey: "MINIMAX_API_KEY", baseUrl: "https://api.minimax.io/v1" },
|
|
78816
78973
|
{ provider: "openrouter", label: "OpenRouter", envKey: "OPENROUTER_API_KEY", baseUrl: "https://openrouter.ai/api/v1" },
|
|
78817
|
-
{ provider: "zai", label: "ZAI", envKey: "ZAI_API_KEY", baseUrl: "https://api.z.ai/api/paas/v4" }
|
|
78974
|
+
{ provider: "zai", label: "ZAI", envKey: "ZAI_API_KEY", baseUrl: "https://api.z.ai/api/paas/v4" },
|
|
78975
|
+
{ provider: "deepseek", label: "DeepSeek", envKey: "DEEPSEEK_API_KEY", baseUrl: "https://api.deepseek.com" }
|
|
78818
78976
|
];
|
|
78819
78977
|
console.log(" [1/3] LLM Provider Configuration\n");
|
|
78820
78978
|
const envProviders = [];
|
|
@@ -78973,7 +79131,8 @@ async function quickInit(options) {
|
|
|
78973
79131
|
const baseUrlMap = {
|
|
78974
79132
|
minimax: "https://api.minimax.io/v1",
|
|
78975
79133
|
siliconflow: "https://api.siliconflow.cn/v1",
|
|
78976
|
-
zai: "https://api.z.ai/api/paas/v4"
|
|
79134
|
+
zai: "https://api.z.ai/api/paas/v4",
|
|
79135
|
+
deepseek: "https://api.deepseek.com"
|
|
78977
79136
|
};
|
|
78978
79137
|
providers[provider] = {
|
|
78979
79138
|
...apiKey ? { apiKey } : {},
|
|
@@ -78986,7 +79145,7 @@ async function quickInit(options) {
|
|
|
78986
79145
|
console.log(" Warning: No API key provided. Configure manually in ~/.markus/markus.json");
|
|
78987
79146
|
}
|
|
78988
79147
|
} else {
|
|
78989
|
-
const provider = await ask(" LLM provider (anthropic/openai/google/minimax/siliconflow/zai/ollama)", "anthropic");
|
|
79148
|
+
const provider = await ask(" LLM provider (anthropic/openai/google/minimax/siliconflow/zai/deepseek/ollama)", "anthropic");
|
|
78990
79149
|
defaultProvider = provider;
|
|
78991
79150
|
let apiKey = "";
|
|
78992
79151
|
if (provider !== "ollama") {
|
|
@@ -78996,7 +79155,8 @@ async function quickInit(options) {
|
|
|
78996
79155
|
const baseUrlMap = {
|
|
78997
79156
|
minimax: "https://api.minimax.io/v1",
|
|
78998
79157
|
siliconflow: "https://api.siliconflow.cn/v1",
|
|
78999
|
-
zai: "https://api.z.ai/api/paas/v4"
|
|
79158
|
+
zai: "https://api.z.ai/api/paas/v4",
|
|
79159
|
+
deepseek: "https://api.deepseek.com"
|
|
79000
79160
|
};
|
|
79001
79161
|
providers[provider] = {
|
|
79002
79162
|
...apiKey ? { apiKey } : {},
|
|
@@ -79032,7 +79192,7 @@ async function quickInit(options) {
|
|
|
79032
79192
|
const userTemplatesDir = pathJoin(homedir19(), ".markus", "templates");
|
|
79033
79193
|
const builtinTemplatesDir = resolveTemplatesDir("roles");
|
|
79034
79194
|
if (builtinTemplatesDir && existsSync32(builtinTemplatesDir) && !existsSync32(userTemplatesDir)) {
|
|
79035
|
-
const builtinRoot =
|
|
79195
|
+
const builtinRoot = resolve15(builtinTemplatesDir, "..");
|
|
79036
79196
|
mkdirSync26(userTemplatesDir, { recursive: true });
|
|
79037
79197
|
cpSync4(builtinRoot, userTemplatesDir, { recursive: true });
|
|
79038
79198
|
console.log(` Copied templates to ${userTemplatesDir}`);
|
|
@@ -79100,7 +79260,7 @@ var start_exports = {};
|
|
|
79100
79260
|
__export(start_exports, {
|
|
79101
79261
|
registerStartCommand: () => registerStartCommand
|
|
79102
79262
|
});
|
|
79103
|
-
import { resolve as
|
|
79263
|
+
import { resolve as resolve16, join as join29, dirname as dirname9 } from "node:path";
|
|
79104
79264
|
import { existsSync as existsSync33 } from "node:fs";
|
|
79105
79265
|
import { homedir as homedir20 } from "node:os";
|
|
79106
79266
|
function registerStartCommand(program2) {
|
|
@@ -79195,6 +79355,19 @@ async function createServices(config) {
|
|
|
79195
79355
|
defaultProvider = "zai";
|
|
79196
79356
|
}
|
|
79197
79357
|
}
|
|
79358
|
+
const deepseekKey = config.llm.providers["deepseek"]?.apiKey ?? process.env["DEEPSEEK_API_KEY"];
|
|
79359
|
+
if (deepseekKey) {
|
|
79360
|
+
providerConfigs["deepseek"] = {
|
|
79361
|
+
provider: "deepseek",
|
|
79362
|
+
model: config.llm.providers["deepseek"]?.model ?? process.env["DEEPSEEK_MODEL"] ?? "deepseek-v4-flash",
|
|
79363
|
+
apiKey: deepseekKey,
|
|
79364
|
+
baseUrl: config.llm.providers["deepseek"]?.baseUrl ?? process.env["DEEPSEEK_BASE_URL"] ?? "https://api.deepseek.com",
|
|
79365
|
+
timeoutMs: llmTimeoutMs
|
|
79366
|
+
};
|
|
79367
|
+
if (config.llm.defaultProvider === "deepseek") {
|
|
79368
|
+
defaultProvider = "deepseek";
|
|
79369
|
+
}
|
|
79370
|
+
}
|
|
79198
79371
|
if (!providerConfigs[defaultProvider]) {
|
|
79199
79372
|
const available = Object.keys(providerConfigs);
|
|
79200
79373
|
if (available.length > 0) {
|
|
@@ -79338,7 +79511,7 @@ async function startServer(config, values) {
|
|
|
79338
79511
|
startupLog("INFO", "\u6B63\u5728\u542F\u52A8\u670D\u52A1...");
|
|
79339
79512
|
const currentPath = process.env["PATH"] ?? "";
|
|
79340
79513
|
const extraPaths = [];
|
|
79341
|
-
const selfBinDir = dirname9(
|
|
79514
|
+
const selfBinDir = dirname9(resolve16(process.argv[1] ?? ""));
|
|
79342
79515
|
if (selfBinDir && !currentPath.includes(selfBinDir)) extraPaths.push(selfBinDir);
|
|
79343
79516
|
const cwdBin = join29(process.cwd(), "node_modules", ".bin");
|
|
79344
79517
|
if (existsSync33(cwdBin) && !currentPath.includes(cwdBin)) extraPaths.push(cwdBin);
|
|
@@ -79480,7 +79653,7 @@ async function startServer(config, values) {
|
|
|
79480
79653
|
});
|
|
79481
79654
|
agentManager.setUserNotifier((opts) => {
|
|
79482
79655
|
hitlService.notify({
|
|
79483
|
-
targetUserId: "
|
|
79656
|
+
targetUserId: "all",
|
|
79484
79657
|
type: opts.type,
|
|
79485
79658
|
title: opts.title,
|
|
79486
79659
|
body: opts.body,
|
|
@@ -79547,7 +79720,7 @@ ${body}`;
|
|
|
79547
79720
|
});
|
|
79548
79721
|
const hasTask = !!taskId2;
|
|
79549
79722
|
hitlService.notify({
|
|
79550
|
-
targetUserId: "
|
|
79723
|
+
targetUserId: "all",
|
|
79551
79724
|
type: "agent_report",
|
|
79552
79725
|
title,
|
|
79553
79726
|
body,
|
|
@@ -79581,7 +79754,7 @@ ${reason}`;
|
|
|
79581
79754
|
isMainSession: true
|
|
79582
79755
|
});
|
|
79583
79756
|
hitlService.notify({
|
|
79584
|
-
targetUserId: "
|
|
79757
|
+
targetUserId: "all",
|
|
79585
79758
|
type: "system",
|
|
79586
79759
|
title: "Agent needs help",
|
|
79587
79760
|
body: reason,
|
|
@@ -79973,7 +80146,7 @@ ${reason}`;
|
|
|
79973
80146
|
temperature: TRIAGE_TEMPERATURE,
|
|
79974
80147
|
maxTokens: TRIAGE_MAX_TOKENS
|
|
79975
80148
|
}, triageProvider);
|
|
79976
|
-
return { content: response.content, toolCalls: response.toolCalls };
|
|
80149
|
+
return { content: response.content, toolCalls: response.toolCalls, reasoningContent: response.reasoningContent };
|
|
79977
80150
|
});
|
|
79978
80151
|
const triageToolMap = /* @__PURE__ */ new Map();
|
|
79979
80152
|
const agentTools = agent.getTools();
|
|
@@ -80688,9 +80861,9 @@ var init_model = __esm({
|
|
|
80688
80861
|
id: "deepseek",
|
|
80689
80862
|
label: "DeepSeek",
|
|
80690
80863
|
envKey: "DEEPSEEK_API_KEY",
|
|
80691
|
-
baseUrl: "https://api.deepseek.com
|
|
80692
|
-
defaultModel: "deepseek-
|
|
80693
|
-
models: ["deepseek-
|
|
80864
|
+
baseUrl: "https://api.deepseek.com",
|
|
80865
|
+
defaultModel: "deepseek-v4-flash",
|
|
80866
|
+
models: ["deepseek-v4-flash", "deepseek-v4-pro", "deepseek-chat", "deepseek-reasoner"]
|
|
80694
80867
|
}
|
|
80695
80868
|
];
|
|
80696
80869
|
C = {
|
|
@@ -81085,7 +81258,7 @@ var init_doctor = __esm({
|
|
|
81085
81258
|
{ id: "siliconflow", label: "SiliconFlow", envKey: "SILICONFLOW_API_KEY", baseUrl: "https://api.siliconflow.cn/v1", defaultModel: "Qwen/Qwen3.5-35B-A3B" },
|
|
81086
81259
|
{ id: "openrouter", label: "OpenRouter", envKey: "OPENROUTER_API_KEY", baseUrl: "https://openrouter.ai/api/v1", defaultModel: "xiaomi/mimo-v2-pro:free" },
|
|
81087
81260
|
{ id: "zai", label: "ZAI", envKey: "ZAI_API_KEY", baseUrl: "https://api.z.ai/api/paas/v4", defaultModel: "glm-5.1" },
|
|
81088
|
-
{ id: "deepseek", label: "DeepSeek", envKey: "DEEPSEEK_API_KEY", baseUrl: "https://api.deepseek.com
|
|
81261
|
+
{ id: "deepseek", label: "DeepSeek", envKey: "DEEPSEEK_API_KEY", baseUrl: "https://api.deepseek.com", defaultModel: "deepseek-v4-flash" }
|
|
81089
81262
|
];
|
|
81090
81263
|
}
|
|
81091
81264
|
});
|
|
@@ -81473,7 +81646,7 @@ var init_auth = __esm({
|
|
|
81473
81646
|
{ id: "siliconflow", label: "SiliconFlow", envKey: "SILICONFLOW_API_KEY", baseUrl: "https://api.siliconflow.cn/v1", defaultModel: "Qwen/Qwen3.5-35B-A3B" },
|
|
81474
81647
|
{ id: "openrouter", label: "OpenRouter", envKey: "OPENROUTER_API_KEY", baseUrl: "https://openrouter.ai/api/v1", defaultModel: "xiaomi/mimo-v2-pro:free" },
|
|
81475
81648
|
{ id: "zai", label: "ZAI", envKey: "ZAI_API_KEY", baseUrl: "https://api.z.ai/api/paas/v4", defaultModel: "glm-5.1" },
|
|
81476
|
-
{ id: "deepseek", label: "DeepSeek", envKey: "DEEPSEEK_API_KEY", defaultModel: "deepseek-
|
|
81649
|
+
{ id: "deepseek", label: "DeepSeek", envKey: "DEEPSEEK_API_KEY", baseUrl: "https://api.deepseek.com", defaultModel: "deepseek-v4-flash" }
|
|
81477
81650
|
];
|
|
81478
81651
|
PLACEHOLDER_PATTERNS3 = ["***", "your-", "dummy", "fake", "test-key", "replace-me"];
|
|
81479
81652
|
}
|
|
@@ -83675,7 +83848,7 @@ __export(skill_exports, {
|
|
|
83675
83848
|
registerSkillCommands: () => registerSkillCommands
|
|
83676
83849
|
});
|
|
83677
83850
|
import { writeFileSync as writeFileSync20, mkdirSync as mkdirSync25 } from "node:fs";
|
|
83678
|
-
import { resolve as
|
|
83851
|
+
import { resolve as resolve17 } from "node:path";
|
|
83679
83852
|
function registerSkillCommands(program2) {
|
|
83680
83853
|
const root = program2.command("skill").description("Skills registry and local scaffold");
|
|
83681
83854
|
root.command("list").action(async (_opts, cmd) => {
|
|
@@ -83763,7 +83936,7 @@ function registerSkillCommands(program2) {
|
|
|
83763
83936
|
const g = cmd.optsWithGlobals();
|
|
83764
83937
|
const out = { json: !!g.json };
|
|
83765
83938
|
if (!opts.dir && !opts.name) fail("Specify --dir or --name");
|
|
83766
|
-
const dir =
|
|
83939
|
+
const dir = resolve17(process.cwd(), opts.dir ?? opts.name);
|
|
83767
83940
|
mkdirSync25(dir, { recursive: true });
|
|
83768
83941
|
const skillName = opts.name ?? (opts.dir ? opts.dir.replace(/.*[/\\]/, "") : "my-skill");
|
|
83769
83942
|
const skillJson = {
|
|
@@ -83782,8 +83955,8 @@ Describe what this skill does for agents.
|
|
|
83782
83955
|
## Tools / behavior
|
|
83783
83956
|
|
|
83784
83957
|
`;
|
|
83785
|
-
writeFileSync20(
|
|
83786
|
-
writeFileSync20(
|
|
83958
|
+
writeFileSync20(resolve17(dir, "skill.json"), JSON.stringify(skillJson, null, 2) + "\n");
|
|
83959
|
+
writeFileSync20(resolve17(dir, "SKILL.md"), skillMd);
|
|
83787
83960
|
if (out.json) {
|
|
83788
83961
|
console.log(JSON.stringify({ dir, files: ["skill.json", "SKILL.md"] }, null, 2));
|
|
83789
83962
|
} else {
|
|
@@ -83807,12 +83980,12 @@ __export(system_exports, {
|
|
|
83807
83980
|
});
|
|
83808
83981
|
import { execSync as execSync6 } from "node:child_process";
|
|
83809
83982
|
import { existsSync as existsSync34, readFileSync as readFileSync25 } from "node:fs";
|
|
83810
|
-
import { resolve as
|
|
83983
|
+
import { resolve as resolve18, dirname as dirname10 } from "node:path";
|
|
83811
83984
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
83812
83985
|
function findMarkusRoot() {
|
|
83813
83986
|
let dir = dirname10(fileURLToPath5(import.meta.url));
|
|
83814
83987
|
for (let i = 0; i < 10; i++) {
|
|
83815
|
-
if (existsSync34(
|
|
83988
|
+
if (existsSync34(resolve18(dir, "package.json")) && existsSync34(resolve18(dir, "packages"))) return dir;
|
|
83816
83989
|
dir = dirname10(dir);
|
|
83817
83990
|
}
|
|
83818
83991
|
return null;
|
|
@@ -83953,13 +84126,13 @@ function registerSystemCommands(program2) {
|
|
|
83953
84126
|
if (markusRoot) {
|
|
83954
84127
|
if (!info4.currentVersion) {
|
|
83955
84128
|
try {
|
|
83956
|
-
const pkg = JSON.parse(readFileSync25(
|
|
84129
|
+
const pkg = JSON.parse(readFileSync25(resolve18(markusRoot, "package.json"), "utf-8"));
|
|
83957
84130
|
info4.currentVersion = pkg.version;
|
|
83958
84131
|
} catch {
|
|
83959
84132
|
}
|
|
83960
84133
|
}
|
|
83961
84134
|
try {
|
|
83962
|
-
const isGit = existsSync34(
|
|
84135
|
+
const isGit = existsSync34(resolve18(markusRoot, ".git"));
|
|
83963
84136
|
if (isGit) {
|
|
83964
84137
|
info4.gitBranch = execSync6("git rev-parse --abbrev-ref HEAD", { cwd: markusRoot, encoding: "utf-8" }).trim();
|
|
83965
84138
|
info4.gitCommit = execSync6("git rev-parse --short HEAD", { cwd: markusRoot, encoding: "utf-8" }).trim();
|
|
@@ -83998,7 +84171,7 @@ function registerSystemCommands(program2) {
|
|
|
83998
84171
|
fail("Cannot locate Markus installation directory");
|
|
83999
84172
|
return;
|
|
84000
84173
|
}
|
|
84001
|
-
if (!existsSync34(
|
|
84174
|
+
if (!existsSync34(resolve18(markusRoot, ".git"))) {
|
|
84002
84175
|
fail("Markus installation is not a git repository. Update manually.");
|
|
84003
84176
|
return;
|
|
84004
84177
|
}
|
|
@@ -84563,7 +84736,7 @@ var init_settings2 = __esm({
|
|
|
84563
84736
|
});
|
|
84564
84737
|
|
|
84565
84738
|
// src/index.ts
|
|
84566
|
-
import { resolve as
|
|
84739
|
+
import { resolve as resolve19 } from "node:path";
|
|
84567
84740
|
import { readFileSync as readFileSync26, existsSync as existsSync35 } from "node:fs";
|
|
84568
84741
|
import process2 from "node:process";
|
|
84569
84742
|
|
|
@@ -84587,7 +84760,7 @@ var {
|
|
|
84587
84760
|
// src/index.ts
|
|
84588
84761
|
init_dist();
|
|
84589
84762
|
init_output();
|
|
84590
|
-
var envPath =
|
|
84763
|
+
var envPath = resolve19(process2.cwd(), ".env");
|
|
84591
84764
|
if (existsSync35(envPath)) {
|
|
84592
84765
|
for (const line of readFileSync26(envPath, "utf-8").split("\n")) {
|
|
84593
84766
|
const trimmed = line.trim();
|