@keyou007/agent-bot 0.1.0
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/.env.example +8 -0
- package/CHANGELOG.md +11 -0
- package/LICENSE +675 -0
- package/README.md +187 -0
- package/README.zh.md +187 -0
- package/SECURITY.md +13 -0
- package/config.example.yaml +56 -0
- package/dist/acp/AcpJsonRpcConnection.js +155 -0
- package/dist/acp/AcpJsonRpcConnection.js.map +1 -0
- package/dist/acp/AcpProcessManager.js +65 -0
- package/dist/acp/AcpProcessManager.js.map +1 -0
- package/dist/acp/AcpSessionManager.js +164 -0
- package/dist/acp/AcpSessionManager.js.map +1 -0
- package/dist/acp/acpTypes.js +10 -0
- package/dist/acp/acpTypes.js.map +1 -0
- package/dist/cli/FeishuAppConfiguration.js +349 -0
- package/dist/cli/FeishuAppConfiguration.js.map +1 -0
- package/dist/cli/FeishuAppRegistration.js +160 -0
- package/dist/cli/FeishuAppRegistration.js.map +1 -0
- package/dist/cli/Initializer.js +112 -0
- package/dist/cli/Initializer.js.map +1 -0
- package/dist/cli/LocalControlClient.js +47 -0
- package/dist/cli/LocalControlClient.js.map +1 -0
- package/dist/cli/LocalControlServer.js +66 -0
- package/dist/cli/LocalControlServer.js.map +1 -0
- package/dist/cli/SkillRegistry.js +126 -0
- package/dist/cli/SkillRegistry.js.map +1 -0
- package/dist/cli/controlProtocol.js +10 -0
- package/dist/cli/controlProtocol.js.map +1 -0
- package/dist/cli/taskChatRoute.js +23 -0
- package/dist/cli/taskChatRoute.js.map +1 -0
- package/dist/cli.js +616 -0
- package/dist/cli.js.map +1 -0
- package/dist/codex/AppServerConnection.js +131 -0
- package/dist/codex/AppServerConnection.js.map +1 -0
- package/dist/codex/CodexEventMapper.js +296 -0
- package/dist/codex/CodexEventMapper.js.map +1 -0
- package/dist/codex/CodexLocalActivityDetector.js +124 -0
- package/dist/codex/CodexLocalActivityDetector.js.map +1 -0
- package/dist/codex/CodexProcessManager.js +64 -0
- package/dist/codex/CodexProcessManager.js.map +1 -0
- package/dist/codex/CodexRuntime.js +825 -0
- package/dist/codex/CodexRuntime.js.map +1 -0
- package/dist/codex/ProjectlessWorkspace.js +74 -0
- package/dist/codex/ProjectlessWorkspace.js.map +1 -0
- package/dist/codex/protocol.js +10 -0
- package/dist/codex/protocol.js.map +1 -0
- package/dist/commands/CommandRouter.js +176 -0
- package/dist/commands/CommandRouter.js.map +1 -0
- package/dist/commands/commandTypes.js +2 -0
- package/dist/commands/commandTypes.js.map +1 -0
- package/dist/config/loadConfig.js +107 -0
- package/dist/config/loadConfig.js.map +1 -0
- package/dist/config/paths.js +32 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/config/schema.js +38 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/console/ConsoleConnector.js +39 -0
- package/dist/console/ConsoleConnector.js.map +1 -0
- package/dist/console/ConsoleTurnPresenter.js +60 -0
- package/dist/console/ConsoleTurnPresenter.js.map +1 -0
- package/dist/feishu/CardRenderer.js +972 -0
- package/dist/feishu/CardRenderer.js.map +1 -0
- package/dist/feishu/CardUpdateScheduler.js +148 -0
- package/dist/feishu/CardUpdateScheduler.js.map +1 -0
- package/dist/feishu/ConsoleFeishuClient.js +18 -0
- package/dist/feishu/ConsoleFeishuClient.js.map +1 -0
- package/dist/feishu/FeishuConnector.js +257 -0
- package/dist/feishu/FeishuConnector.js.map +1 -0
- package/dist/feishu/FeishuMarkdown.js +37 -0
- package/dist/feishu/FeishuMarkdown.js.map +1 -0
- package/dist/feishu/FeishuMessageClient.js +459 -0
- package/dist/feishu/FeishuMessageClient.js.map +1 -0
- package/dist/feishu/FeishuTurnPresenter.js +425 -0
- package/dist/feishu/FeishuTurnPresenter.js.map +1 -0
- package/dist/feishu/GroupAvatarGenerator.js +86 -0
- package/dist/feishu/GroupAvatarGenerator.js.map +1 -0
- package/dist/feishu/LocalCardImage.js +13 -0
- package/dist/feishu/LocalCardImage.js.map +1 -0
- package/dist/feishu/LocalImageMarkdown.js +89 -0
- package/dist/feishu/LocalImageMarkdown.js.map +1 -0
- package/dist/feishu/contextKey.js +12 -0
- package/dist/feishu/contextKey.js.map +1 -0
- package/dist/feishu/transport.js +14 -0
- package/dist/feishu/transport.js.map +1 -0
- package/dist/feishu/types.js +2 -0
- package/dist/feishu/types.js.map +1 -0
- package/dist/index.js +213 -0
- package/dist/index.js.map +1 -0
- package/dist/logging/logger.js +22 -0
- package/dist/logging/logger.js.map +1 -0
- package/dist/presentation/OutboundRouter.js +127 -0
- package/dist/presentation/OutboundRouter.js.map +1 -0
- package/dist/presentation/TurnStateReducer.js +307 -0
- package/dist/presentation/TurnStateReducer.js.map +1 -0
- package/dist/presentation/splitMarkdown.js +341 -0
- package/dist/presentation/splitMarkdown.js.map +1 -0
- package/dist/presentation/turnViewTypes.js +2 -0
- package/dist/presentation/turnViewTypes.js.map +1 -0
- package/dist/proxy/ProxySessionController.js +2819 -0
- package/dist/proxy/ProxySessionController.js.map +1 -0
- package/dist/runtime/AcpRuntimeAdapter.js +271 -0
- package/dist/runtime/AcpRuntimeAdapter.js.map +1 -0
- package/dist/runtime/AgentRuntimeRegistry.js +18 -0
- package/dist/runtime/AgentRuntimeRegistry.js.map +1 -0
- package/dist/runtime/agentEnvironment.js +11 -0
- package/dist/runtime/agentEnvironment.js.map +1 -0
- package/dist/runtime/types.js +2 -0
- package/dist/runtime/types.js.map +1 -0
- package/dist/startup/SessionMetadataHydrator.js +46 -0
- package/dist/startup/SessionMetadataHydrator.js.map +1 -0
- package/dist/startup/StartupNotifier.js +78 -0
- package/dist/startup/StartupNotifier.js.map +1 -0
- package/dist/startup/startFeishu.js +6 -0
- package/dist/startup/startFeishu.js.map +1 -0
- package/dist/state/StateStore.js +893 -0
- package/dist/state/StateStore.js.map +1 -0
- package/dist/state/migrations.js +129 -0
- package/dist/state/migrations.js.map +1 -0
- package/dist/supervision/SafeRestartNotifier.js +116 -0
- package/dist/supervision/SafeRestartNotifier.js.map +1 -0
- package/dist/supervision/SafeRestartScheduler.js +123 -0
- package/dist/supervision/SafeRestartScheduler.js.map +1 -0
- package/dist/supervision/replacementSupervisor.js +8 -0
- package/dist/supervision/replacementSupervisor.js.map +1 -0
- package/dist/supervision/restartPolicy.js +16 -0
- package/dist/supervision/restartPolicy.js.map +1 -0
- package/dist/supervisor.js +94 -0
- package/dist/supervisor.js.map +1 -0
- package/dist/utils/executeShellCommand.js +76 -0
- package/dist/utils/executeShellCommand.js.map +1 -0
- package/dist/utils/id.js +5 -0
- package/dist/utils/id.js.map +1 -0
- package/dist/utils/markdown.js +29 -0
- package/dist/utils/markdown.js.map +1 -0
- package/dist/utils/spawnCommand.js +21 -0
- package/dist/utils/spawnCommand.js.map +1 -0
- package/dist/utils/taskTitle.js +10 -0
- package/dist/utils/taskTitle.js.map +1 -0
- package/docs/technical-reference.md +294 -0
- package/docs/technical-reference.zh.md +294 -0
- package/npm-shrinkwrap.json +4525 -0
- package/package.json +87 -0
- package/skills/agent-bot/SKILL.md +141 -0
- package/skills/agent-bot/agents/openai.yaml +4 -0
- package/src/acp/AcpJsonRpcConnection.ts +212 -0
- package/src/acp/AcpProcessManager.ts +87 -0
- package/src/acp/AcpSessionManager.ts +227 -0
- package/src/acp/acpTypes.ts +99 -0
- package/src/cli/FeishuAppConfiguration.ts +473 -0
- package/src/cli/FeishuAppRegistration.ts +207 -0
- package/src/cli/Initializer.ts +159 -0
- package/src/cli/LocalControlClient.ts +48 -0
- package/src/cli/LocalControlServer.ts +67 -0
- package/src/cli/SkillRegistry.ts +151 -0
- package/src/cli/controlProtocol.ts +34 -0
- package/src/cli/taskChatRoute.ts +31 -0
- package/src/cli.ts +630 -0
- package/src/codex/AppServerConnection.ts +159 -0
- package/src/codex/CodexEventMapper.ts +351 -0
- package/src/codex/CodexLocalActivityDetector.ts +148 -0
- package/src/codex/CodexProcessManager.ts +63 -0
- package/src/codex/CodexRuntime.ts +1025 -0
- package/src/codex/ProjectlessWorkspace.ts +90 -0
- package/src/codex/protocol.ts +37 -0
- package/src/commands/CommandRouter.ts +179 -0
- package/src/commands/commandTypes.ts +28 -0
- package/src/config/loadConfig.ts +115 -0
- package/src/config/paths.ts +37 -0
- package/src/config/schema.ts +46 -0
- package/src/console/ConsoleConnector.ts +40 -0
- package/src/console/ConsoleTurnPresenter.ts +64 -0
- package/src/feishu/CardRenderer.ts +1157 -0
- package/src/feishu/CardUpdateScheduler.ts +165 -0
- package/src/feishu/ConsoleFeishuClient.ts +22 -0
- package/src/feishu/FeishuConnector.ts +277 -0
- package/src/feishu/FeishuMarkdown.ts +47 -0
- package/src/feishu/FeishuMessageClient.ts +649 -0
- package/src/feishu/FeishuTurnPresenter.ts +539 -0
- package/src/feishu/GroupAvatarGenerator.ts +102 -0
- package/src/feishu/LocalCardImage.ts +13 -0
- package/src/feishu/LocalImageMarkdown.ts +92 -0
- package/src/feishu/contextKey.ts +14 -0
- package/src/feishu/transport.ts +24 -0
- package/src/feishu/types.ts +83 -0
- package/src/index.ts +228 -0
- package/src/logging/logger.ts +28 -0
- package/src/presentation/OutboundRouter.ts +205 -0
- package/src/presentation/TurnStateReducer.ts +341 -0
- package/src/presentation/splitMarkdown.ts +358 -0
- package/src/presentation/turnViewTypes.ts +54 -0
- package/src/proxy/ProxySessionController.ts +3311 -0
- package/src/runtime/AcpRuntimeAdapter.ts +324 -0
- package/src/runtime/AgentRuntimeRegistry.ts +20 -0
- package/src/runtime/agentEnvironment.ts +14 -0
- package/src/runtime/types.ts +215 -0
- package/src/startup/SessionMetadataHydrator.ts +46 -0
- package/src/startup/StartupNotifier.ts +92 -0
- package/src/startup/startFeishu.ts +19 -0
- package/src/state/StateStore.ts +1249 -0
- package/src/state/migrations.ts +128 -0
- package/src/supervision/SafeRestartNotifier.ts +122 -0
- package/src/supervision/SafeRestartScheduler.ts +149 -0
- package/src/supervision/replacementSupervisor.ts +10 -0
- package/src/supervision/restartPolicy.ts +19 -0
- package/src/supervisor.ts +106 -0
- package/src/utils/executeShellCommand.ts +97 -0
- package/src/utils/id.ts +5 -0
- package/src/utils/markdown.ts +25 -0
- package/src/utils/spawnCommand.ts +35 -0
- package/src/utils/taskTitle.ts +9 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
const DEFAULT_TIMEOUT_MS = 120_000;
|
|
3
|
+
const DEFAULT_MAX_OUTPUT_BYTES = 64 * 1024;
|
|
4
|
+
export function executeShellCommand(command, cwd, options = {}) {
|
|
5
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
6
|
+
const maxOutputBytes = options.maxOutputBytes ?? DEFAULT_MAX_OUTPUT_BYTES;
|
|
7
|
+
const prepared = prepareShellCommand(command, options.platform ?? process.platform);
|
|
8
|
+
return new Promise((resolve, reject) => {
|
|
9
|
+
const child = spawn(prepared.command, prepared.args, {
|
|
10
|
+
cwd,
|
|
11
|
+
env: process.env,
|
|
12
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
13
|
+
windowsHide: true,
|
|
14
|
+
});
|
|
15
|
+
const output = new BoundedOutput(maxOutputBytes);
|
|
16
|
+
let timedOut = false;
|
|
17
|
+
const timeout = setTimeout(() => {
|
|
18
|
+
timedOut = true;
|
|
19
|
+
child.kill();
|
|
20
|
+
}, timeoutMs);
|
|
21
|
+
child.stdout.on("data", (chunk) => output.append("stdout", chunk));
|
|
22
|
+
child.stderr.on("data", (chunk) => output.append("stderr", chunk));
|
|
23
|
+
child.once("error", (error) => {
|
|
24
|
+
clearTimeout(timeout);
|
|
25
|
+
reject(error);
|
|
26
|
+
});
|
|
27
|
+
child.once("close", (exitCode) => {
|
|
28
|
+
clearTimeout(timeout);
|
|
29
|
+
resolve({
|
|
30
|
+
...output.result(),
|
|
31
|
+
exitCode,
|
|
32
|
+
timedOut,
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
function prepareShellCommand(command, platform) {
|
|
38
|
+
if (platform !== "win32")
|
|
39
|
+
return { command: "/bin/sh", args: ["-lc", command] };
|
|
40
|
+
const script = `$ProgressPreference = 'SilentlyContinue'; [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new(); ${command}`;
|
|
41
|
+
const encoded = Buffer.from(script, "utf16le").toString("base64");
|
|
42
|
+
return {
|
|
43
|
+
command: "powershell.exe",
|
|
44
|
+
args: ["-NoLogo", "-NoProfile", "-NonInteractive", "-OutputFormat", "Text", "-EncodedCommand", encoded],
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
class BoundedOutput {
|
|
48
|
+
maxBytes;
|
|
49
|
+
stdout = [];
|
|
50
|
+
stderr = [];
|
|
51
|
+
retainedBytes = 0;
|
|
52
|
+
truncated = false;
|
|
53
|
+
constructor(maxBytes) {
|
|
54
|
+
this.maxBytes = maxBytes;
|
|
55
|
+
}
|
|
56
|
+
append(stream, chunk) {
|
|
57
|
+
const remaining = Math.max(0, this.maxBytes - this.retainedBytes);
|
|
58
|
+
if (remaining === 0) {
|
|
59
|
+
this.truncated = true;
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const retained = chunk.length <= remaining ? chunk : chunk.subarray(0, remaining);
|
|
63
|
+
this[stream].push(retained);
|
|
64
|
+
this.retainedBytes += retained.length;
|
|
65
|
+
if (retained.length < chunk.length)
|
|
66
|
+
this.truncated = true;
|
|
67
|
+
}
|
|
68
|
+
result() {
|
|
69
|
+
return {
|
|
70
|
+
stdout: Buffer.concat(this.stdout).toString("utf8"),
|
|
71
|
+
stderr: Buffer.concat(this.stderr).toString("utf8"),
|
|
72
|
+
outputTruncated: this.truncated,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=executeShellCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executeShellCommand.js","sourceRoot":"","sources":["../../src/utils/executeShellCommand.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/id.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id.js","sourceRoot":"","sources":["../../src/utils/id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,UAAU,QAAQ,CAAC,MAAc;IACrC,OAAO,GAAG,MAAM,IAAI,UAAU,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;AACtE,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export function truncateText(text, maxLength = 8000) {
|
|
2
|
+
if (text.length <= maxLength)
|
|
3
|
+
return text;
|
|
4
|
+
if (maxLength <= 0)
|
|
5
|
+
return "";
|
|
6
|
+
if (maxLength <= 3)
|
|
7
|
+
return ".".repeat(maxLength);
|
|
8
|
+
return `${text.slice(0, maxLength - 3)}...`;
|
|
9
|
+
}
|
|
10
|
+
export function truncateMiddle(text, maxLength = 8000, marker = "\n...\n") {
|
|
11
|
+
if (text.length <= maxLength)
|
|
12
|
+
return text;
|
|
13
|
+
if (maxLength <= 0)
|
|
14
|
+
return "";
|
|
15
|
+
if (maxLength <= marker.length)
|
|
16
|
+
return ".".repeat(maxLength);
|
|
17
|
+
const retainedLength = maxLength - marker.length;
|
|
18
|
+
const headLength = Math.ceil(retainedLength / 2);
|
|
19
|
+
const tailLength = Math.floor(retainedLength / 2);
|
|
20
|
+
return `${text.slice(0, headLength)}${marker}${text.slice(text.length - tailLength)}`;
|
|
21
|
+
}
|
|
22
|
+
export function codeBlock(text, language = "") {
|
|
23
|
+
const fenceSafe = text.replaceAll("```", "`\u200b``");
|
|
24
|
+
return `\`\`\`${language}\n${fenceSafe}\n\`\`\``;
|
|
25
|
+
}
|
|
26
|
+
export function asInlineCode(text) {
|
|
27
|
+
return `\`${text.replaceAll("`", "'")}\``;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/utils/markdown.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,SAAS,GAAG,IAAI;IACzD,IAAI,IAAI,CAAC,MAAM,IAAI,SAAS;QAAE,OAAO,IAAI,CAAC;IAC1C,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAC9B,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACjD,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,SAAS,GAAG,IAAI,EAAE,MAAM,GAAG,SAAS;IAC/E,IAAI,IAAI,CAAC,MAAM,IAAI,SAAS;QAAE,OAAO,IAAI,CAAC;IAC1C,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IAC9B,IAAI,SAAS,IAAI,MAAM,CAAC,MAAM;QAAE,OAAO,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC7D,MAAM,cAAc,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;IACjD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC;IACjD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC;IAClD,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,EAAE,CAAC;AACxF,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,QAAQ,GAAG,EAAE;IACnD,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IACtD,OAAO,SAAS,QAAQ,KAAK,SAAS,UAAU,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,KAAK,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
export function prepareCommand(command, args, platform = process.platform, comspec = process.env.ComSpec ?? process.env.COMSPEC ?? "cmd.exe") {
|
|
3
|
+
if (platform !== "win32")
|
|
4
|
+
return { command, args };
|
|
5
|
+
const commandLine = [command, ...args].map(quoteCmdToken).join(" ");
|
|
6
|
+
return { command: comspec, args: ["/d", "/s", "/c", commandLine] };
|
|
7
|
+
}
|
|
8
|
+
export function spawnStdioCommand(command, args, env) {
|
|
9
|
+
const prepared = prepareCommand(command, args);
|
|
10
|
+
return spawn(prepared.command, prepared.args, {
|
|
11
|
+
env,
|
|
12
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
13
|
+
windowsHide: true,
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
function quoteCmdToken(value) {
|
|
17
|
+
if (value.length > 0 && !/[\s"&|<>^()%!]/.test(value))
|
|
18
|
+
return value;
|
|
19
|
+
return `"${value.replaceAll('"', '""')}"`;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=spawnCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spawnCommand.js","sourceRoot":"","sources":["../../src/utils/spawnCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAuC,MAAM,oBAAoB,CAAC;AAOhF,MAAM,UAAU,cAAc,CAC5B,OAAe,EACf,IAAc,EACd,QAAQ,GAAoB,OAAO,CAAC,QAAQ,EAC5C,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,SAAS;IAEjE,IAAI,QAAQ,KAAK,OAAO;QAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACnD,MAAM,WAAW,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,EAAE,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,OAAe,EACf,IAAc,EACd,GAAsB;IAEtB,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC/C,OAAO,KAAK,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE;QAC5C,GAAG;QACH,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;QAC/B,WAAW,EAAE,IAAI;KAClB,CAAC,CAAC;AACL,CAAC;AAED,SAAS,aAAa,CAAC,KAAa;IAClC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACpE,OAAO,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC;AAC5C,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
const MAX_TASK_TITLE_LENGTH = 120;
|
|
2
|
+
export function normalizeTaskTitle(value) {
|
|
3
|
+
const normalized = value?.replace(/\s+/g, " ").trim();
|
|
4
|
+
if (!normalized)
|
|
5
|
+
return undefined;
|
|
6
|
+
return normalized.length <= MAX_TASK_TITLE_LENGTH
|
|
7
|
+
? normalized
|
|
8
|
+
: `${normalized.slice(0, MAX_TASK_TITLE_LENGTH - 3)}...`;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=taskTitle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"taskTitle.js","sourceRoot":"","sources":["../../src/utils/taskTitle.ts"],"names":[],"mappings":"AAAA,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAElC,MAAM,UAAU,kBAAkB,CAAC,KAAgC;IACjE,MAAM,UAAU,GAAG,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACtD,IAAI,CAAC,UAAU;QAAE,OAAO,SAAS,CAAC;IAClC,OAAO,UAAU,CAAC,MAAM,IAAI,qBAAqB;QAC/C,CAAC,CAAC,UAAU;QACZ,CAAC,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC;AAC7D,CAAC"}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
# Agent Bot Technical Reference
|
|
2
|
+
|
|
3
|
+
English | [简体中文](technical-reference.zh.md)
|
|
4
|
+
|
|
5
|
+
This document covers deployment, configuration, runtime behavior, persistence, and integration details. For installation and everyday commands, start with the [README](../README.md).
|
|
6
|
+
|
|
7
|
+
## Runtime Architecture
|
|
8
|
+
|
|
9
|
+
Agent Bot is a Node.js 22+ ESM TypeScript application built around these components:
|
|
10
|
+
|
|
11
|
+
- The supervisor owns the long-running service and restarts the worker.
|
|
12
|
+
- The worker starts the configured Codex and ACP runtimes, Feishu transport, Console transport, local control server, and SQLite store.
|
|
13
|
+
- Feishu events and Console input are normalized into the same task controller.
|
|
14
|
+
- Presentation components maintain one progress card per turn and send the final Markdown response separately.
|
|
15
|
+
- Codex agents use Codex App Server over stdio; other configured agents use ACP.
|
|
16
|
+
|
|
17
|
+
Relevant source areas:
|
|
18
|
+
|
|
19
|
+
| Area | Responsibility |
|
|
20
|
+
| ------------------- | ------------------------------------------------------------------------- |
|
|
21
|
+
| `src/config/` | YAML loading, environment expansion, validation, and path resolution |
|
|
22
|
+
| `src/cli/` | Initialization, app registration, app auditing, and service/task commands |
|
|
23
|
+
| `src/feishu/` | Feishu WebSocket events, API calls, cards, images, and context keys |
|
|
24
|
+
| `src/runtime/` | Shared runtime abstraction |
|
|
25
|
+
| `src/codex/` | Codex App Server protocol integration |
|
|
26
|
+
| `src/acp/` | ACP process and JSON-RPC integration |
|
|
27
|
+
| `src/proxy/` | Tasks, turns, steering, queues, forks, and command execution |
|
|
28
|
+
| `src/presentation/` | Turn-state reduction and outbound routing |
|
|
29
|
+
| `src/state/` | SQLite schema, migrations, routing, and delivery state |
|
|
30
|
+
| `src/supervision/` | Safe restart and restart notifications |
|
|
31
|
+
|
|
32
|
+
## User Data And Path Resolution
|
|
33
|
+
|
|
34
|
+
The default user-data root is `~/.agent-bot`. `AGENT_BOT_HOME` replaces that root.
|
|
35
|
+
|
|
36
|
+
| Default path | Contents |
|
|
37
|
+
| ------------------------------------ | ---------------------------------- |
|
|
38
|
+
| `~/.agent-bot/config.yaml` | Main YAML configuration |
|
|
39
|
+
| `~/.agent-bot/.env` | Feishu credentials |
|
|
40
|
+
| `~/.agent-bot/data/agent-bot.sqlite` | Persistent task and delivery state |
|
|
41
|
+
| `~/.agent-bot/data/inbound-images/` | Cached incoming images |
|
|
42
|
+
| `~/.agent-bot/logs/agent-bot.log` | Structured runtime logs |
|
|
43
|
+
|
|
44
|
+
Configuration path precedence:
|
|
45
|
+
|
|
46
|
+
1. CLI `--config <path>`
|
|
47
|
+
2. `AGENT_BOT_CONFIG`
|
|
48
|
+
3. `~/.agent-bot/config.yaml`
|
|
49
|
+
|
|
50
|
+
The default `.env` is always loaded from the Agent Bot home. YAML values in the form `${NAME}` are expanded from the process environment after `.env` loading.
|
|
51
|
+
|
|
52
|
+
Relative `storage.sqlitePath` and `logging.path` values resolve against the directory containing the loaded configuration file. `defaults.cwd` resolves against the process startup directory.
|
|
53
|
+
|
|
54
|
+
## Initialization
|
|
55
|
+
|
|
56
|
+
`agent-bot init` copies the packaged `config.example.yaml` and `.env.example` when their target files do not exist, creates the data and log directories, and restricts `.env` permissions where the platform supports POSIX modes.
|
|
57
|
+
|
|
58
|
+
Credential behavior:
|
|
59
|
+
|
|
60
|
+
- Environment values take precedence over values in `~/.agent-bot/.env`.
|
|
61
|
+
- Both `FEISHU_APP_ID` and `FEISHU_APP_SECRET` are required.
|
|
62
|
+
- Complete credentials are preserved unless `--reconfigure-feishu` is used.
|
|
63
|
+
- An incomplete credential pair is rejected instead of being silently replaced.
|
|
64
|
+
- Newly registered credentials are written atomically to `.env`.
|
|
65
|
+
|
|
66
|
+
When credentials are absent, initialization uses Feishu one-click registration and reports its verification URL as text and a QR code. After registration, or when complete credentials already exist, it audits the currently published app version.
|
|
67
|
+
|
|
68
|
+
Missing app configuration is handled in two stages:
|
|
69
|
+
|
|
70
|
+
1. Core configuration is requested and polled until it becomes available.
|
|
71
|
+
2. Remaining optional configuration is requested without blocking initialization.
|
|
72
|
+
|
|
73
|
+
The generated authorization links do not contain the app secret.
|
|
74
|
+
|
|
75
|
+
## Feishu App Requirements
|
|
76
|
+
|
|
77
|
+
Core configuration required for basic messaging:
|
|
78
|
+
|
|
79
|
+
- Bot capability
|
|
80
|
+
- Persistent-connection event delivery
|
|
81
|
+
- `im.message.receive_v1`
|
|
82
|
+
- Tenant permissions for group @ messages and private messages
|
|
83
|
+
- `im:message:send_as_bot` or a broader equivalent
|
|
84
|
+
- `application:application:self_manage` so initialization can inspect the published version
|
|
85
|
+
|
|
86
|
+
Optional configuration:
|
|
87
|
+
|
|
88
|
+
| Configuration | Enabled behavior |
|
|
89
|
+
| ------------------------------------- | ---------------------------- |
|
|
90
|
+
| `im:chat:create` | `/newgroup` and `/forkgroup` |
|
|
91
|
+
| `im:chat:read` | Reading group metadata |
|
|
92
|
+
| `im.chat.updated_v1` | Group-title synchronization |
|
|
93
|
+
| `im:message.reactions:write_only` | Processing-status reactions |
|
|
94
|
+
| Message-read and resource permissions | Incoming and outgoing images |
|
|
95
|
+
| Image and chat permissions | Generated group avatars |
|
|
96
|
+
| `card.action.trigger` | Interactive card actions |
|
|
97
|
+
|
|
98
|
+
Optional authorization failures are returned in the final initialization result with the affected feature names. Rerunning `agent-bot init` repeats the audit.
|
|
99
|
+
|
|
100
|
+
## Configuration Model
|
|
101
|
+
|
|
102
|
+
The complete example is [config.example.yaml](../config.example.yaml). The main sections are:
|
|
103
|
+
|
|
104
|
+
```yaml
|
|
105
|
+
feishu:
|
|
106
|
+
transport: "auto"
|
|
107
|
+
appId: "${FEISHU_APP_ID}"
|
|
108
|
+
appSecret: "${FEISHU_APP_SECRET}"
|
|
109
|
+
useConsoleWhenMissingCredentials: true
|
|
110
|
+
|
|
111
|
+
console:
|
|
112
|
+
enabled: true
|
|
113
|
+
|
|
114
|
+
agents:
|
|
115
|
+
codex:
|
|
116
|
+
kind: "codex"
|
|
117
|
+
title: "Codex"
|
|
118
|
+
command: "codex"
|
|
119
|
+
args: ["app-server", "--enable", "goals", "--listen", "stdio://"]
|
|
120
|
+
env: {}
|
|
121
|
+
|
|
122
|
+
defaults:
|
|
123
|
+
agent: "codex"
|
|
124
|
+
cwd: "."
|
|
125
|
+
|
|
126
|
+
storage:
|
|
127
|
+
sqlitePath: "./data/agent-bot.sqlite"
|
|
128
|
+
|
|
129
|
+
logging:
|
|
130
|
+
level: "info"
|
|
131
|
+
path: "./logs/agent-bot.log"
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
`feishu.transport` accepts:
|
|
135
|
+
|
|
136
|
+
- `auto`: use the SDK when credentials exist; otherwise follow `useConsoleWhenMissingCredentials`
|
|
137
|
+
- `sdk`: require Feishu credentials and start the WebSocket client
|
|
138
|
+
- `console`: disable Feishu transport
|
|
139
|
+
|
|
140
|
+
At least one agent must be configured. `defaults.agent` must name a configured agent.
|
|
141
|
+
|
|
142
|
+
## Agent Runtimes
|
|
143
|
+
|
|
144
|
+
An agent with `kind: "codex"` uses Codex App Server. Agent Bot passes project directory, model, reasoning effort, permission mode, text input, and local images through the App Server protocol.
|
|
145
|
+
|
|
146
|
+
An agent with `kind: "acp"`, or without a `kind`, is started as an ACP process. Agent-specific `env` values are added to its environment.
|
|
147
|
+
|
|
148
|
+
Every agent process receives:
|
|
149
|
+
|
|
150
|
+
```text
|
|
151
|
+
AGENT_BOT=1
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
The bundled skill uses this variable to detect that it is running inside Agent Bot.
|
|
155
|
+
|
|
156
|
+
## Chat Routing
|
|
157
|
+
|
|
158
|
+
The message route determines the current task:
|
|
159
|
+
|
|
160
|
+
- A private chat body is isolated by its Feishu chat ID.
|
|
161
|
+
- A group timeline is isolated by its Feishu chat ID.
|
|
162
|
+
- A message with a thread ID is isolated as its own thread context.
|
|
163
|
+
- Console input uses a separate local context.
|
|
164
|
+
|
|
165
|
+
Commands, card callbacks, progress cards, and final responses stay on the originating route.
|
|
166
|
+
|
|
167
|
+
Starting a Feishu thread from a mapped user message, progress card, or final response forks from the associated completed Codex turn. If no reliable completed source turn exists, the operation fails instead of selecting an arbitrary point.
|
|
168
|
+
|
|
169
|
+
`/forkgroup` has thread-aware source selection. An unbound thread, or a bound thread task with no completed turn of its own, forks directly from the thread's original anchor turn without creating an intermediate thread task. Once the thread task has completed a turn, `/forkgroup` uses its latest locally persisted completed turn. A newer active turn does not block the command and is excluded from the fork point.
|
|
170
|
+
|
|
171
|
+
## Turn And Message Behavior
|
|
172
|
+
|
|
173
|
+
- Plain text creates a task when the route has no current task.
|
|
174
|
+
- Text received during an active Codex turn is sent through steering.
|
|
175
|
+
- A steering race at turn completion becomes the next queued request.
|
|
176
|
+
- `/nosteer` always creates a persistent FIFO queue item.
|
|
177
|
+
- Queue card actions can cancel individual pending items.
|
|
178
|
+
- Unknown slash commands are rejected and never forwarded as Prompts.
|
|
179
|
+
|
|
180
|
+
Each turn owns one progress card. Normal updates are throttled to one every two seconds; critical updates have a 500 ms minimum gap. On completion, Agent Bot updates the progress card to a terminal state before sending a separate final Markdown message.
|
|
181
|
+
|
|
182
|
+
After message deduplication, Agent Bot attempts an `OnIt` reaction. It replaces that reaction with `DONE`, `ERROR`, or `CrossMark` when the turn succeeds, fails, or is canceled. Reaction failures do not block task execution.
|
|
183
|
+
|
|
184
|
+
Incoming rich-text images are downloaded into the inbound image cache and passed to Codex as `localImage` inputs. An image-only message uses the default Prompt `请分析这张图片。`. An ACP runtime that cannot accept image input returns an explicit error.
|
|
185
|
+
|
|
186
|
+
## Tasks, Projects, And External Codex Work
|
|
187
|
+
|
|
188
|
+
`/sessions` reads Codex tasks through `thread/list` and can discover tasks created by Codex Desktop, CLI, Agent Bot, or another App Server client under the same `CODEX_HOME`.
|
|
189
|
+
|
|
190
|
+
Agent Bot keeps a local routing key for Feishu cards and delivery state, but presents the Codex task ID to users. It does not resume, steer, stop, or fork externally running Codex work without an explicit user action.
|
|
191
|
+
|
|
192
|
+
Project behavior:
|
|
193
|
+
|
|
194
|
+
- `/new --dir <path>` creates a project task.
|
|
195
|
+
- `/new --nodir` creates a Projectless task.
|
|
196
|
+
- `/new` inherits the current task's project or Projectless shape.
|
|
197
|
+
- A first Projectless task is created under `~/Documents/Codex/<date>/<task-name>`.
|
|
198
|
+
- An existing task's working directory is immutable.
|
|
199
|
+
|
|
200
|
+
Forks use the latest available completed turn and do not interrupt an active source turn.
|
|
201
|
+
|
|
202
|
+
## Persistence And Recovery
|
|
203
|
+
|
|
204
|
+
SQLite stores:
|
|
205
|
+
|
|
206
|
+
- Current and previous tasks for each route
|
|
207
|
+
- Local and Codex task/thread identifiers
|
|
208
|
+
- Model, reasoning effort, and permission mode
|
|
209
|
+
- Queued Prompts
|
|
210
|
+
- Progress snapshots and message bindings
|
|
211
|
+
- Final-message delivery records
|
|
212
|
+
|
|
213
|
+
On startup, Agent Bot reconciles persisted active work with Codex through `thread/read`. It also reconciles when turn identifiers change, terminal notifications arrive, or control requests fail.
|
|
214
|
+
|
|
215
|
+
The final-delivery ledger prevents duplicate successful replies. App Server requests use finite timeouts so a stalled request cannot permanently occupy a message route.
|
|
216
|
+
|
|
217
|
+
## Supervisor And Restart
|
|
218
|
+
|
|
219
|
+
`agent-bot server start` starts a detached supervisor. The supervisor restarts the worker after unexpected exits and applies exponential backoff from one to 30 seconds after repeated crashes.
|
|
220
|
+
|
|
221
|
+
A safe restart waits for:
|
|
222
|
+
|
|
223
|
+
1. Active tasks to finish
|
|
224
|
+
2. Final responses to be delivered
|
|
225
|
+
3. A 15-second quiet inbound-message window
|
|
226
|
+
|
|
227
|
+
New messages reset the quiet timer. `--immediate` and `--force` skip these checks. Exit code `75` identifies an intentional worker restart.
|
|
228
|
+
|
|
229
|
+
The first safe-restart status card is delayed by three seconds so a task's final response can usually arrive first. Status changes during that window are coalesced into the initial card. The delay does not block scheduler polling, and shutdown flushes any pending card immediately.
|
|
230
|
+
|
|
231
|
+
The local control server implements task mutations and service restart requests. Read-only task queries access SQLite directly.
|
|
232
|
+
|
|
233
|
+
## Permission Modes
|
|
234
|
+
|
|
235
|
+
- `auto`: Codex runs with `approvalPolicy=never` and `danger-full-access`.
|
|
236
|
+
- `confirm`: approval requests are presented through card actions for one-time approval, session approval, denial, or task cancellation.
|
|
237
|
+
|
|
238
|
+
Model, reasoning effort, permission mode, and project shape are inherited where applicable when creating or forking tasks.
|
|
239
|
+
|
|
240
|
+
## Managed System Skill
|
|
241
|
+
|
|
242
|
+
The packaged Agent Bot skill can be installed into the shared agent skill directory:
|
|
243
|
+
|
|
244
|
+
```powershell
|
|
245
|
+
agent-bot skills install
|
|
246
|
+
agent-bot skills status
|
|
247
|
+
agent-bot skills uninstall
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
The default target is `~/.agents/skills`. `AGENT_BOT_SKILLS_DIR` or `--target` selects another root. Installation is a managed copy; uninstall does not remove an unrelated same-named directory.
|
|
251
|
+
|
|
252
|
+
## npm Package And Releases
|
|
253
|
+
|
|
254
|
+
The public package is `@keyou007/agent-bot`; its executable remains `agent-bot`. The package uses a `files` allowlist so runtime code, templates, the managed skill, source code, and user-facing documentation are published without tests or internal design plans.
|
|
255
|
+
|
|
256
|
+
`npm-shrinkwrap.json` is published with the CLI to keep transitive runtime dependencies reproducible. Direct runtime and development dependencies are also pinned to exact versions.
|
|
257
|
+
|
|
258
|
+
Package lifecycle:
|
|
259
|
+
|
|
260
|
+
- `prepublishOnly` runs type checking and the full test suite.
|
|
261
|
+
- `prepack` builds a clean `dist/` and validates the tarball manifest.
|
|
262
|
+
- `npm run package:smoke` packs the project, installs the tarball into a temporary directory, runs the CLI, and performs Console-only initialization.
|
|
263
|
+
|
|
264
|
+
The first public release requires an npm account that owns the `@keyou007` scope:
|
|
265
|
+
|
|
266
|
+
```powershell
|
|
267
|
+
npm login
|
|
268
|
+
npm ci
|
|
269
|
+
npm run verify
|
|
270
|
+
npm run package:smoke
|
|
271
|
+
npm publish --access public
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
After the first release, configure an npm Trusted Publisher for:
|
|
275
|
+
|
|
276
|
+
- GitHub owner: `keyou`
|
|
277
|
+
- Repository: `agent-bot`
|
|
278
|
+
- Workflow: `publish.yml`
|
|
279
|
+
- Allowed action: `npm publish`
|
|
280
|
+
|
|
281
|
+
The publish workflow is triggered by a GitHub Release whose tag exactly matches `v<package version>`. It uses GitHub OIDC instead of a long-lived npm token and publishes from a GitHub-hosted Node.js 24 runner.
|
|
282
|
+
|
|
283
|
+
## Development And Source Installation
|
|
284
|
+
|
|
285
|
+
```powershell
|
|
286
|
+
npm ci
|
|
287
|
+
npm run dev
|
|
288
|
+
npm run typecheck
|
|
289
|
+
npm test
|
|
290
|
+
npm run build
|
|
291
|
+
npm link
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
`npm link` registers the checkout's `agent-bot` executable globally. Without it, built CLI commands can be invoked through `npm run cli --`. `npm run dev` runs one foreground worker, while `npm start` runs the supervisor in the current terminal.
|