@amical/aiagent-sdk 0.1.7 → 0.1.9
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.d.mts +11 -3
- package/dist/index.d.ts +11 -3
- package/dist/index.js +61 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +61 -6
- package/dist/index.mjs.map +1 -1
- package/dist/runtime/nodeRuntime.d.mts +3 -3
- package/dist/runtime/nodeRuntime.d.ts +3 -3
- package/dist/runtime/nodeRuntime.js +94 -16
- package/dist/runtime/nodeRuntime.js.map +1 -1
- package/dist/runtime/nodeRuntime.mjs +93 -15
- package/dist/runtime/nodeRuntime.mjs.map +1 -1
- package/dist/runtime/webRuntime.d.mts +3 -2
- package/dist/runtime/webRuntime.d.ts +3 -2
- package/dist/runtime/webRuntime.js +85 -10
- package/dist/runtime/webRuntime.js.map +1 -1
- package/dist/runtime/webRuntime.mjs +85 -10
- package/dist/runtime/webRuntime.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -4,7 +4,7 @@ import { streamText } from 'ai';
|
|
|
4
4
|
import { createOpenAI } from '@ai-sdk/openai';
|
|
5
5
|
import { createDifyProvider } from 'dify-ai-provider';
|
|
6
6
|
import * as fs2 from 'fs/promises';
|
|
7
|
-
import * as
|
|
7
|
+
import * as path from 'path';
|
|
8
8
|
import * as os from 'os';
|
|
9
9
|
import { exec } from 'child_process';
|
|
10
10
|
import { promisify } from 'util';
|
|
@@ -555,7 +555,7 @@ var ClineAgent = class {
|
|
|
555
555
|
}
|
|
556
556
|
}
|
|
557
557
|
/**
|
|
558
|
-
* 获取当前 Agent 的系统提示词
|
|
558
|
+
* 获取当前 Agent 的系统提示词
|
|
559
559
|
* 如果 force 为 true,则强制重新获取系统提示词
|
|
560
560
|
*/
|
|
561
561
|
async getPrompt(force = false) {
|
|
@@ -693,9 +693,12 @@ ${content.trim()}\`\`\``);
|
|
|
693
693
|
const history = await this.memory.getHistory();
|
|
694
694
|
const stream = this.api.createMessage(sysPrompt, history);
|
|
695
695
|
let fullResponseText = "";
|
|
696
|
+
let fullReasoningText = "";
|
|
696
697
|
for await (const chunk of stream) {
|
|
697
698
|
if (chunk.type === "text" && chunk.text) {
|
|
698
699
|
fullResponseText += chunk.text;
|
|
700
|
+
} else if (chunk.type === "reasoning" && chunk.reasoning) {
|
|
701
|
+
fullReasoningText += chunk.reasoning;
|
|
699
702
|
}
|
|
700
703
|
if (this.onStreamChunk) {
|
|
701
704
|
this.onStreamChunk(chunk);
|
|
@@ -703,7 +706,8 @@ ${content.trim()}\`\`\``);
|
|
|
703
706
|
}
|
|
704
707
|
await this.memory.appendMessage({
|
|
705
708
|
role: "assistant",
|
|
706
|
-
content: fullResponseText
|
|
709
|
+
content: fullResponseText,
|
|
710
|
+
...fullReasoningText ? { reasoning: fullReasoningText } : {}
|
|
707
711
|
});
|
|
708
712
|
const parsedBlocks = parseAssistantMessageV2(fullResponseText, this.allToolParamNames);
|
|
709
713
|
const toolUses = parsedBlocks.filter((b) => b.type === "tool_use");
|
|
@@ -826,15 +830,20 @@ STDERR: ${result.stderr}` });
|
|
|
826
830
|
const path3 = tool.params.path || this.runtime.env.cwd();
|
|
827
831
|
const regexStr = tool.params.regex;
|
|
828
832
|
const filePattern = tool.params.file_pattern;
|
|
829
|
-
if (regexStr &&
|
|
833
|
+
if (regexStr && path3) {
|
|
830
834
|
try {
|
|
831
|
-
|
|
835
|
+
let result;
|
|
836
|
+
if (typeof this.runtime.fs.searchFiles === "function") {
|
|
837
|
+
result = await this.runtime.fs.searchFiles(path3, regexStr, filePattern);
|
|
838
|
+
} else {
|
|
839
|
+
result = await this.searchFiles(path3, regexStr, filePattern);
|
|
840
|
+
}
|
|
832
841
|
toolResults.push({ tool, result: `${result}` });
|
|
833
842
|
} catch (e) {
|
|
834
843
|
toolResults.push({ tool, result: `Error: ${e.message}` });
|
|
835
844
|
}
|
|
836
845
|
} else {
|
|
837
|
-
toolResults.push({ tool, result: `Error:
|
|
846
|
+
toolResults.push({ tool, result: `Error: miss path or regex params` });
|
|
838
847
|
}
|
|
839
848
|
} else if (tool.name === "agent_use_mcp_tool" /* MCP_USE */) {
|
|
840
849
|
const serverName = tool.params.server_name;
|
|
@@ -939,9 +948,14 @@ IMPORTANT: The skill is now loaded. Do NOT call agent_load_skill again for this
|
|
|
939
948
|
}
|
|
940
949
|
}
|
|
941
950
|
if (this.state === "thinking" /* THINKING */ && toolResults.length > 0) {
|
|
942
|
-
|
|
951
|
+
let toolResultsContext = toolResults.map((tr) => `<${TOOL_RESULT_BLOCK} tool_name="${tr.tool.name}">
|
|
943
952
|
${typeof tr.result === "string" ? tr.result.trim() : JSON.stringify(tr.result)}
|
|
944
953
|
</${TOOL_RESULT_BLOCK}>`).join("\n\n");
|
|
954
|
+
const lastResult = toolResults[toolResults.length - 1];
|
|
955
|
+
if (lastResult && lastResult.tool.name !== "agent_attempt_completion" /* ATTEMPT */) {
|
|
956
|
+
toolResultsContext += `
|
|
957
|
+
${this.promptManager.getUsedToolResultInstructions()}`;
|
|
958
|
+
}
|
|
945
959
|
if (this.onStreamChunk) {
|
|
946
960
|
this.onStreamChunk({ type: "text", text: toolResultsContext });
|
|
947
961
|
}
|
|
@@ -999,6 +1013,47 @@ ${searchBlock.substring(0, 100)}...`);
|
|
|
999
1013
|
async getHistory() {
|
|
1000
1014
|
return this.memory.getHistory();
|
|
1001
1015
|
}
|
|
1016
|
+
async searchFiles(dirpath, regex, filePattern) {
|
|
1017
|
+
const matches = [];
|
|
1018
|
+
const contentRe = new RegExp(regex);
|
|
1019
|
+
const nameRe = filePattern ? new RegExp(filePattern.replace(/\./g, "\\.").replace(/\*/g, ".*")) : null;
|
|
1020
|
+
const SKIP_DIRS = /* @__PURE__ */ new Set([".git", "dist", ".agent", ".turbopack"]);
|
|
1021
|
+
const walk = async (dir, depth) => {
|
|
1022
|
+
if (depth > 8 || matches.length >= 100) {
|
|
1023
|
+
return;
|
|
1024
|
+
}
|
|
1025
|
+
let entries;
|
|
1026
|
+
try {
|
|
1027
|
+
entries = await this.runtime.fs.readDir(dir, { recursive: false });
|
|
1028
|
+
} catch {
|
|
1029
|
+
return;
|
|
1030
|
+
}
|
|
1031
|
+
for (const entry of entries) {
|
|
1032
|
+
if (matches.length >= 100) {
|
|
1033
|
+
break;
|
|
1034
|
+
}
|
|
1035
|
+
const child = dir === "." ? entry.name : `${dir}/${entry.name}`;
|
|
1036
|
+
if (entry.isDirectory()) {
|
|
1037
|
+
if (!SKIP_DIRS.has(entry.name)) {
|
|
1038
|
+
await walk(child, depth + 1);
|
|
1039
|
+
}
|
|
1040
|
+
} else if (entry.isFile()) {
|
|
1041
|
+
if (nameRe && !nameRe.test(entry.name)) {
|
|
1042
|
+
continue;
|
|
1043
|
+
}
|
|
1044
|
+
try {
|
|
1045
|
+
const content = (await this.runtime.fs.readFile(child, "utf8")).toString();
|
|
1046
|
+
if (contentRe.test(content)) {
|
|
1047
|
+
matches.push(child);
|
|
1048
|
+
}
|
|
1049
|
+
} catch {
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
};
|
|
1054
|
+
await walk(dirpath, 0);
|
|
1055
|
+
return matches.join("\n");
|
|
1056
|
+
}
|
|
1002
1057
|
};
|
|
1003
1058
|
var NodeApiHandler = class {
|
|
1004
1059
|
config;
|
|
@@ -1061,6 +1116,11 @@ var NodeApiHandler = class {
|
|
|
1061
1116
|
type: "text",
|
|
1062
1117
|
text: part.textDelta || part.text || ""
|
|
1063
1118
|
};
|
|
1119
|
+
} else if (part.type === "reasoning-delta") {
|
|
1120
|
+
yield {
|
|
1121
|
+
type: "reasoning",
|
|
1122
|
+
reasoning: part.delta || part.text || ""
|
|
1123
|
+
};
|
|
1064
1124
|
} else if (part.type === "finish") {
|
|
1065
1125
|
yield {
|
|
1066
1126
|
type: "usage",
|
|
@@ -1368,6 +1428,21 @@ Otherwise, if you have not completed the task and do not need additional informa
|
|
|
1368
1428
|
(This is an automated message, so do not respond to it conversationally.)
|
|
1369
1429
|
${this?.getEnvironmentInfoPrompt?.(context)}`;
|
|
1370
1430
|
}
|
|
1431
|
+
getUsedToolResultInstructions() {
|
|
1432
|
+
return `The above are the results of the tool call. Please continue to complete the remaining tasks.
|
|
1433
|
+
|
|
1434
|
+
# TODO LIST UPDATE REQUIRED - You MUST include the task_progress parameter in your NEXT tool call.
|
|
1435
|
+
|
|
1436
|
+
1. To create or update a todo list, include the task_progress parameter in the next tool call
|
|
1437
|
+
2. Review each item and update its status:
|
|
1438
|
+
- Mark completed items with: - [x]
|
|
1439
|
+
- Keep incomplete items as: - [ ]
|
|
1440
|
+
- Add new items if you discover additional steps
|
|
1441
|
+
3. Modify the list as needed:
|
|
1442
|
+
- Add any new steps you've discovered
|
|
1443
|
+
- Reorder if the sequence has changed
|
|
1444
|
+
4. Ensure the list accurately reflects the current state`;
|
|
1445
|
+
}
|
|
1371
1446
|
};
|
|
1372
1447
|
var NodeMemoryManager = class {
|
|
1373
1448
|
filePath;
|
|
@@ -1377,14 +1452,14 @@ var NodeMemoryManager = class {
|
|
|
1377
1452
|
* @param maxMessages 保留的最大消息数量,用于简单的历史截断(默认 150)
|
|
1378
1453
|
*/
|
|
1379
1454
|
constructor(dbPath, maxMessages = 150) {
|
|
1380
|
-
this.filePath =
|
|
1455
|
+
this.filePath = path.resolve(dbPath);
|
|
1381
1456
|
this.maxMessages = maxMessages;
|
|
1382
1457
|
}
|
|
1383
1458
|
async ensureFile() {
|
|
1384
1459
|
try {
|
|
1385
1460
|
await fs2.access(this.filePath);
|
|
1386
1461
|
} catch {
|
|
1387
|
-
const dir =
|
|
1462
|
+
const dir = path.dirname(this.filePath);
|
|
1388
1463
|
await fs2.mkdir(dir, { recursive: true });
|
|
1389
1464
|
await fs2.writeFile(this.filePath, "[]", "utf-8");
|
|
1390
1465
|
}
|
|
@@ -1560,10 +1635,13 @@ var NodeMcpManager = class {
|
|
|
1560
1635
|
var execAsync = promisify(exec);
|
|
1561
1636
|
var DefaultNodeRuntime = class {
|
|
1562
1637
|
fs = {
|
|
1563
|
-
readFile: async (filepath) => fs2.readFile(filepath,
|
|
1638
|
+
readFile: async (filepath, options = "utf8") => fs2.readFile(filepath, options),
|
|
1564
1639
|
writeFile: async (filepath, content) => {
|
|
1565
|
-
|
|
1566
|
-
|
|
1640
|
+
const dir = filepath.substring(0, filepath.lastIndexOf("/"));
|
|
1641
|
+
if (dir && dir !== filepath) {
|
|
1642
|
+
await fs2.mkdir(dir, { recursive: true });
|
|
1643
|
+
}
|
|
1644
|
+
await fs2.writeFile(filepath, content, "utf8");
|
|
1567
1645
|
},
|
|
1568
1646
|
deleteFile: (filepath) => fs2.unlink(filepath),
|
|
1569
1647
|
deleteDirectory: (dirpath) => fs2.rm(dirpath, { recursive: true, force: true }),
|
|
@@ -1575,13 +1653,13 @@ var DefaultNodeRuntime = class {
|
|
|
1575
1653
|
return false;
|
|
1576
1654
|
}
|
|
1577
1655
|
},
|
|
1578
|
-
readDir: (dirpath) => fs2.readdir(dirpath, { withFileTypes: true }),
|
|
1656
|
+
readDir: (dirpath, options) => fs2.readdir(dirpath, { withFileTypes: true, ...options || {} }),
|
|
1579
1657
|
mkdir: async (dirpath) => {
|
|
1580
1658
|
await fs2.mkdir(dirpath, { recursive: true });
|
|
1581
1659
|
}
|
|
1582
1660
|
};
|
|
1583
1661
|
path = {
|
|
1584
|
-
join: (...paths) =>
|
|
1662
|
+
join: (...paths) => path.join(...paths)
|
|
1585
1663
|
};
|
|
1586
1664
|
env = {
|
|
1587
1665
|
get: (key) => process.env[key],
|
|
@@ -1603,7 +1681,7 @@ var DefaultNodeRuntime = class {
|
|
|
1603
1681
|
function createNodeAgent(options) {
|
|
1604
1682
|
const runtime = new DefaultNodeRuntime();
|
|
1605
1683
|
const api = new NodeApiHandler(options.apiConfig);
|
|
1606
|
-
const memory = options.memory || new NodeMemoryManager(options.dbPath ||
|
|
1684
|
+
const memory = options.memory || new NodeMemoryManager(options.dbPath || path.join(runtime.env.cwd(), ".cline_memory.json"));
|
|
1607
1685
|
const customTools = options.customTools || [];
|
|
1608
1686
|
const customToolNames = new Set(customTools.map((t) => t.name));
|
|
1609
1687
|
const promptManager = new NodePromptManager();
|