@keyou007/agent-bot 0.1.20-alpha.1 → 0.1.21
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/CHANGELOG.md +21 -0
- package/README.md +27 -4
- package/README.zh.md +23 -4
- package/dist/cli/AgentPrerequisites.js +11 -47
- package/dist/cli/AgentPrerequisites.js.map +1 -1
- package/dist/cli/DefaultAgentSelection.js +1 -1
- package/dist/cli/DefaultAgentSelection.js.map +1 -1
- package/dist/cli.js +15 -0
- package/dist/cli.js.map +1 -1
- package/dist/codex/CodexEventMapper.js +21 -1
- package/dist/codex/CodexEventMapper.js.map +1 -1
- package/dist/codex/CodexLocalActivityDetector.js +32 -10
- package/dist/codex/CodexLocalActivityDetector.js.map +1 -1
- package/dist/codex/CodexProcessManager.js +56 -7
- package/dist/codex/CodexProcessManager.js.map +1 -1
- package/dist/codex/CodexRuntime.js +361 -168
- package/dist/codex/CodexRuntime.js.map +1 -1
- package/dist/codex/CodexVersion.js +18 -0
- package/dist/codex/CodexVersion.js.map +1 -0
- package/dist/codex/ProviderModels.js +159 -0
- package/dist/codex/ProviderModels.js.map +1 -0
- package/dist/codex/ProviderSwitch.js +32 -0
- package/dist/codex/ProviderSwitch.js.map +1 -0
- package/dist/commands/CommandRouter.js +8 -3
- package/dist/commands/CommandRouter.js.map +1 -1
- package/dist/console/ConsoleTurnPresenter.js +2 -1
- package/dist/console/ConsoleTurnPresenter.js.map +1 -1
- package/dist/feishu/CardRenderer.js +82 -27
- package/dist/feishu/CardRenderer.js.map +1 -1
- package/dist/feishu/FeishuConnector.js +17 -5
- package/dist/feishu/FeishuConnector.js.map +1 -1
- package/dist/feishu/FeishuTurnPresenter.js +34 -8
- package/dist/feishu/FeishuTurnPresenter.js.map +1 -1
- package/dist/feishu/InboundText.js +11 -0
- package/dist/feishu/InboundText.js.map +1 -1
- package/dist/feishu/MergedForwardMessage.js +17 -5
- package/dist/feishu/MergedForwardMessage.js.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/local-files/LocalFileViewerServer.js +164 -19
- package/dist/local-files/LocalFileViewerServer.js.map +1 -1
- package/dist/local-files/MarkdownFileLinks.js +65 -0
- package/dist/local-files/MarkdownFileLinks.js.map +1 -0
- package/dist/local-files/TurnPreviewPage.js +725 -0
- package/dist/local-files/TurnPreviewPage.js.map +1 -0
- package/dist/presentation/OutboundRouter.js +6 -1
- package/dist/presentation/OutboundRouter.js.map +1 -1
- package/dist/presentation/TurnStateReducer.js +142 -3
- package/dist/presentation/TurnStateReducer.js.map +1 -1
- package/dist/proxy/ProxySessionController.js +573 -325
- package/dist/proxy/ProxySessionController.js.map +1 -1
- package/dist/state/StateStore.js +65 -65
- package/dist/state/StateStore.js.map +1 -1
- package/dist/utils/formatStorageSize.js +15 -0
- package/dist/utils/formatStorageSize.js.map +1 -0
- package/dist/utils/semanticVersion.js +39 -0
- package/dist/utils/semanticVersion.js.map +1 -0
- package/docs/technical-reference.md +11 -3
- package/docs/technical-reference.zh.md +11 -3
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/skills/agent-bot/SKILL.md +11 -1
- package/src/cli/AgentPrerequisites.ts +14 -40
- package/src/cli/DefaultAgentSelection.ts +1 -1
- package/src/cli.ts +13 -0
- package/src/codex/CodexEventMapper.ts +31 -1
- package/src/codex/CodexLocalActivityDetector.ts +41 -9
- package/src/codex/CodexProcessManager.ts +48 -7
- package/src/codex/CodexRuntime.ts +397 -204
- package/src/codex/CodexVersion.ts +18 -0
- package/src/codex/ProviderModels.ts +185 -0
- package/src/codex/ProviderSwitch.ts +36 -0
- package/src/commands/CommandRouter.ts +7 -2
- package/src/commands/commandTypes.ts +1 -1
- package/src/console/ConsoleTurnPresenter.ts +3 -0
- package/src/feishu/CardRenderer.ts +84 -43
- package/src/feishu/FeishuConnector.ts +15 -5
- package/src/feishu/FeishuTurnPresenter.ts +46 -4
- package/src/feishu/InboundText.ts +11 -0
- package/src/feishu/MergedForwardMessage.ts +15 -5
- package/src/index.ts +3 -1
- package/src/local-files/LocalFileViewerServer.ts +179 -20
- package/src/local-files/MarkdownFileLinks.ts +64 -0
- package/src/local-files/TurnPreviewPage.ts +792 -0
- package/src/presentation/OutboundRouter.ts +8 -0
- package/src/presentation/TurnStateReducer.ts +175 -2
- package/src/presentation/turnViewTypes.ts +13 -0
- package/src/proxy/ProxySessionController.ts +547 -297
- package/src/runtime/types.ts +33 -3
- package/src/state/StateStore.ts +86 -90
- package/src/utils/formatStorageSize.ts +13 -0
- package/src/utils/semanticVersion.ts +28 -0
|
@@ -2,6 +2,13 @@ import { createHash } from "node:crypto";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { truncateMiddle, truncateText } from "../utils/markdown.js";
|
|
4
4
|
import { localCardImage } from "./LocalCardImage.js";
|
|
5
|
+
const EXECUTION_SETTING_EFFECTS = {
|
|
6
|
+
agent: "只影响新建任务,不切换当前任务。",
|
|
7
|
+
provider: "只影响当前任务,需空闲时切换。",
|
|
8
|
+
model: "只影响当前任务,下一轮生效。",
|
|
9
|
+
thinking: "只影响当前任务,下一轮生效。",
|
|
10
|
+
permission: "只影响当前任务,下一轮生效。",
|
|
11
|
+
};
|
|
5
12
|
const DIRECTORY_BROWSER_ROW_COUNT = 16;
|
|
6
13
|
export class CardRenderer {
|
|
7
14
|
thinkingCardLayout;
|
|
@@ -234,7 +241,7 @@ export class CardRenderer {
|
|
|
234
241
|
];
|
|
235
242
|
if (view.activeTab === "agent") {
|
|
236
243
|
elements.push(...view.agents.map((agent) => settingsOptionRow({
|
|
237
|
-
label:
|
|
244
|
+
label: inlineCode(agent.name),
|
|
238
245
|
current: agent.name === view.currentAgent,
|
|
239
246
|
action: {
|
|
240
247
|
text: "Switch",
|
|
@@ -257,9 +264,6 @@ export class CardRenderer {
|
|
|
257
264
|
elements.push(...view.providers.map((provider) => settingsOptionRow({
|
|
258
265
|
label: [
|
|
259
266
|
inlineCode(provider.id),
|
|
260
|
-
provider.displayName && provider.displayName !== provider.id
|
|
261
|
-
? ` · ${escapeCardHtml(provider.displayName)}`
|
|
262
|
-
: "",
|
|
263
267
|
provider.isDefault ? " · 默认" : "",
|
|
264
268
|
].join(""),
|
|
265
269
|
current: provider.id === view.currentProvider,
|
|
@@ -331,6 +335,7 @@ export class CardRenderer {
|
|
|
331
335
|
},
|
|
332
336
|
})));
|
|
333
337
|
}
|
|
338
|
+
elements.push(markdown(`> ${EXECUTION_SETTING_EFFECTS[view.activeTab]}`));
|
|
334
339
|
return sectionCard("运行设置", elements, view.notice ? "green" : "blue");
|
|
335
340
|
}
|
|
336
341
|
renderProviderSelector(view) {
|
|
@@ -812,7 +817,7 @@ export class CardRenderer {
|
|
|
812
817
|
},
|
|
813
818
|
};
|
|
814
819
|
}
|
|
815
|
-
renderTurn(state) {
|
|
820
|
+
renderTurn(state, previewUrl) {
|
|
816
821
|
const elements = this.thinkingCardLayout === "timeline"
|
|
817
822
|
? renderTurnElements(state, "hidden")
|
|
818
823
|
: renderGroupedTurnElements(state, "hidden");
|
|
@@ -823,17 +828,26 @@ export class CardRenderer {
|
|
|
823
828
|
type: "danger",
|
|
824
829
|
value: { action: "turn_cancel", sessionId: state.sessionId, turnId: state.turnId },
|
|
825
830
|
});
|
|
826
|
-
|
|
831
|
+
if (previewUrl)
|
|
832
|
+
footerActions.push(turnPreviewAction(previewUrl));
|
|
833
|
+
elements.push({ tag: "hr" }, taskActionRow(footerActions, renderTurnDuration(state), true));
|
|
827
834
|
}
|
|
828
835
|
else if (state.status === "completed") {
|
|
829
836
|
footerActions.push({
|
|
830
837
|
text: "Reset",
|
|
831
838
|
value: { action: "turn_reset", sessionId: state.sessionId, turnId: state.turnId },
|
|
832
839
|
});
|
|
833
|
-
|
|
840
|
+
if (previewUrl)
|
|
841
|
+
footerActions.push(turnPreviewAction(previewUrl));
|
|
842
|
+
elements.push({ tag: "hr" }, taskActionRow(footerActions, undefined, true));
|
|
834
843
|
}
|
|
835
844
|
else if (state.status === "starting") {
|
|
836
|
-
|
|
845
|
+
if (previewUrl)
|
|
846
|
+
footerActions.push(turnPreviewAction(previewUrl));
|
|
847
|
+
elements.push({ tag: "hr" }, taskActionRow(footerActions, renderTurnDuration(state), true));
|
|
848
|
+
}
|
|
849
|
+
else if (previewUrl) {
|
|
850
|
+
elements.push({ tag: "hr" }, taskActionRow([turnPreviewAction(previewUrl)], renderTurnDuration(state)));
|
|
837
851
|
}
|
|
838
852
|
if (state.status === "completed") {
|
|
839
853
|
elements.push({
|
|
@@ -843,11 +857,17 @@ export class CardRenderer {
|
|
|
843
857
|
}
|
|
844
858
|
return turnCard(turnTitle(state.status, state.prompt ?? state.taskTitle), turnTemplate(state.status), elements, renderTurnSubtitle(state));
|
|
845
859
|
}
|
|
846
|
-
renderTurnDetails(state) {
|
|
860
|
+
renderTurnDetails(state, previewUrl) {
|
|
847
861
|
const title = state.taskTitle
|
|
848
862
|
? `任务执行详情:${truncateText(state.taskTitle.replace(/\s+/g, " ").trim(), 60)}`
|
|
849
863
|
: "任务执行详情";
|
|
850
|
-
|
|
864
|
+
const elements = [markdown(`Turn: \`${state.turnId}\``)];
|
|
865
|
+
if (state.prompt)
|
|
866
|
+
elements.push(markdown(`**Prompt**\n${truncateText(state.prompt, 1_000)}`));
|
|
867
|
+
elements.push(...renderTurnElements(state, "always"));
|
|
868
|
+
if (previewUrl)
|
|
869
|
+
elements.push(taskActionRow([turnPreviewAction(previewUrl)]));
|
|
870
|
+
return turnCard(title, "blue", elements, renderTurnSubtitle(state));
|
|
851
871
|
}
|
|
852
872
|
renderActivityHistory(state, requestedPage) {
|
|
853
873
|
const grouped = this.thinkingCardLayout === "grouped";
|
|
@@ -1152,9 +1172,9 @@ export class CardRenderer {
|
|
|
1152
1172
|
elements.push(markdown("当前任务还没有成功完成的 turn。"));
|
|
1153
1173
|
}
|
|
1154
1174
|
else {
|
|
1175
|
+
const sequenceWidth = `${Math.max(16, ...view.entries.map((entry) => String(entry.sequence).length * 10))}px`;
|
|
1155
1176
|
view.entries.forEach((entry) => {
|
|
1156
|
-
|
|
1157
|
-
elements.push(resetHistoryEntryRow(entry.graphNodeLine, entry.graphConnectorLine, entry.lines, entry.timestamp, action, entry.current === true, entry.running === true, entry.resetting === true));
|
|
1177
|
+
elements.push(resetHistoryEntryRow(entry, sequenceWidth));
|
|
1158
1178
|
});
|
|
1159
1179
|
}
|
|
1160
1180
|
if (view.footerLines.length > 0) {
|
|
@@ -1791,7 +1811,7 @@ function renderToolDetails(tool, projectCwd) {
|
|
|
1791
1811
|
const resultText = result ? truncateToolResult(normalizeTerminalOutput(result).trim()) : undefined;
|
|
1792
1812
|
return codeBlock([`$ ${commandText}`, resultText].filter((part) => part !== undefined).join("\n"), 2_003);
|
|
1793
1813
|
}
|
|
1794
|
-
function formatShellCommandForDisplay(command) {
|
|
1814
|
+
export function formatShellCommandForDisplay(command) {
|
|
1795
1815
|
const normalized = command.replace(/\r\n/g, "\n");
|
|
1796
1816
|
let result = "";
|
|
1797
1817
|
let quote;
|
|
@@ -1892,7 +1912,7 @@ function toolPanelTitle(tool) {
|
|
|
1892
1912
|
const command = stripAnsi(tool.command ?? tool.title).trim();
|
|
1893
1913
|
const meaningfulCommand = tool.kind === "web_search"
|
|
1894
1914
|
? tool.title
|
|
1895
|
-
:
|
|
1915
|
+
: displayToolCommand(command) ?? tool.title;
|
|
1896
1916
|
const duration = toolDuration(tool);
|
|
1897
1917
|
const prefix = `${icon} `;
|
|
1898
1918
|
const suffix = duration ? ` · ${duration}` : "";
|
|
@@ -1957,6 +1977,10 @@ function shellCommandStatus(view) {
|
|
|
1957
1977
|
}
|
|
1958
1978
|
return { title: "命令执行失败", label: `退出码 ${view.exitCode ?? "未知"}`, template: "red" };
|
|
1959
1979
|
}
|
|
1980
|
+
export function displayToolCommand(command) {
|
|
1981
|
+
const clean = stripAnsi(command).trim();
|
|
1982
|
+
return unwrapShellCommand(clean);
|
|
1983
|
+
}
|
|
1960
1984
|
function unwrapShellCommand(command) {
|
|
1961
1985
|
return unwrapPowerShellCommand(command) ?? unwrapPosixShellCommand(command);
|
|
1962
1986
|
}
|
|
@@ -2295,16 +2319,29 @@ function settingsOptionRow(input) {
|
|
|
2295
2319
|
],
|
|
2296
2320
|
};
|
|
2297
2321
|
}
|
|
2298
|
-
function resetHistoryEntryRow(
|
|
2322
|
+
function resetHistoryEntryRow(entry, sequenceWidth) {
|
|
2323
|
+
const { graphNodeLine, graphConnectorLine, lines, timestamp, current, running, resetting } = entry;
|
|
2324
|
+
const action = entry.actions?.[0];
|
|
2299
2325
|
const branchConnectorLine = graphConnectorLine && /[╱╲]/u.test(graphConnectorLine)
|
|
2300
2326
|
? graphConnectorLine
|
|
2301
2327
|
: undefined;
|
|
2302
|
-
const
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2328
|
+
const color = current ? "green" : running || resetting ? "orange" : "blue";
|
|
2329
|
+
const nodeLanes = graphNodeLine.match(/[●│]/gu) ?? [];
|
|
2330
|
+
const connectorLanes = branchConnectorLine?.split(" ");
|
|
2331
|
+
// Each lane has its own center; shorter connectors and wider turn numbers cannot shift it.
|
|
2332
|
+
const graphColumns = nodeLanes.map((node, lane) => ({
|
|
2333
|
+
tag: "column",
|
|
2334
|
+
width: "16px",
|
|
2335
|
+
vertical_align: "top",
|
|
2336
|
+
padding: "0px",
|
|
2337
|
+
elements: [{
|
|
2338
|
+
...markdown([
|
|
2339
|
+
`<font color='${color}'>${node}</font>`,
|
|
2340
|
+
...(connectorLanes?.[lane] ? [`<font color='grey'>${escapeCardHtml(connectorLanes[lane])}</font>`] : []),
|
|
2341
|
+
].join("\n")),
|
|
2342
|
+
text_align: "center",
|
|
2343
|
+
}],
|
|
2344
|
+
}));
|
|
2308
2345
|
const trailingElements = current
|
|
2309
2346
|
? [markdown("✅ 当前")]
|
|
2310
2347
|
: resetting
|
|
@@ -2325,8 +2362,20 @@ function resetHistoryEntryRow(graphNodeLine, graphConnectorLine, lines, timestam
|
|
|
2325
2362
|
width: "auto",
|
|
2326
2363
|
vertical_align: "top",
|
|
2327
2364
|
elements: [{
|
|
2328
|
-
|
|
2329
|
-
|
|
2365
|
+
tag: "column_set",
|
|
2366
|
+
flex_mode: "none",
|
|
2367
|
+
horizontal_spacing: "0px",
|
|
2368
|
+
horizontal_align: "left",
|
|
2369
|
+
columns: [
|
|
2370
|
+
...graphColumns,
|
|
2371
|
+
{
|
|
2372
|
+
tag: "column",
|
|
2373
|
+
width: sequenceWidth,
|
|
2374
|
+
vertical_align: "top",
|
|
2375
|
+
padding: "0px",
|
|
2376
|
+
elements: [{ ...markdown(`<font color='${color}'>${entry.sequence}</font>`), text_align: "left" }],
|
|
2377
|
+
},
|
|
2378
|
+
],
|
|
2330
2379
|
}],
|
|
2331
2380
|
},
|
|
2332
2381
|
{
|
|
@@ -2444,10 +2493,16 @@ function taskActionElement(action) {
|
|
|
2444
2493
|
padding: "0px",
|
|
2445
2494
|
has_border: false,
|
|
2446
2495
|
elements: [markdown(`<font color='${action.type === "danger" ? "red" : "blue"}'>${escapeCardActionText(action.text)}</font>`)],
|
|
2447
|
-
behaviors:
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2496
|
+
behaviors: action.url
|
|
2497
|
+
? [{ type: "open_url", default_url: action.url }]
|
|
2498
|
+
: [{ type: "callback", value: action.value }],
|
|
2499
|
+
};
|
|
2500
|
+
}
|
|
2501
|
+
function turnPreviewAction(previewUrl) {
|
|
2502
|
+
return {
|
|
2503
|
+
text: "Preview",
|
|
2504
|
+
value: {},
|
|
2505
|
+
url: previewUrl,
|
|
2451
2506
|
};
|
|
2452
2507
|
}
|
|
2453
2508
|
function escapeCardActionText(value) {
|