@keyou007/agent-bot 0.1.24-alpha.4 → 0.1.24-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +59 -0
- package/README.md +42 -6
- package/README.zh.md +42 -6
- package/SECURITY.md +12 -0
- package/config.example.yaml +5 -0
- package/dist/cli/controlProtocol.js.map +1 -1
- package/dist/cli/serverStatus.js +1 -0
- package/dist/cli/serverStatus.js.map +1 -1
- package/dist/cli.js +6 -1
- package/dist/cli.js.map +1 -1
- package/dist/codex/AppServerPermissions.js +34 -0
- package/dist/codex/AppServerPermissions.js.map +1 -0
- package/dist/codex/CodexLocalActivityDetector.js +37 -5
- package/dist/codex/CodexLocalActivityDetector.js.map +1 -1
- package/dist/codex/CodexRuntime.js +238 -127
- package/dist/codex/CodexRuntime.js.map +1 -1
- package/dist/codex/ProviderSwitch.js +12 -13
- package/dist/codex/ProviderSwitch.js.map +1 -1
- package/dist/codex/ThreadWriterProcess.js +19 -5
- package/dist/codex/ThreadWriterProcess.js.map +1 -1
- package/dist/config/AgentExecutionDefaultsStore.js +4 -0
- package/dist/config/AgentExecutionDefaultsStore.js.map +1 -1
- package/dist/config/loadConfig.js +4 -0
- package/dist/config/loadConfig.js.map +1 -1
- package/dist/config/schema.js +3 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/feishu/CardRenderer.js +146 -72
- package/dist/feishu/CardRenderer.js.map +1 -1
- package/dist/feishu/FeishuConnector.js +1 -0
- package/dist/feishu/FeishuConnector.js.map +1 -1
- package/dist/feishu/FeishuTurnPresenter.js +121 -17
- package/dist/feishu/FeishuTurnPresenter.js.map +1 -1
- package/dist/index.js +43 -6
- package/dist/index.js.map +1 -1
- package/dist/local-files/CsvPreview.js +148 -0
- package/dist/local-files/CsvPreview.js.map +1 -0
- package/dist/local-files/LocalFileViewerServer.js +104 -14
- package/dist/local-files/LocalFileViewerServer.js.map +1 -1
- package/dist/local-files/TurnPreviewPage.js +128 -12
- package/dist/local-files/TurnPreviewPage.js.map +1 -1
- package/dist/presentation/TurnStateReducer.js +80 -6
- package/dist/presentation/TurnStateReducer.js.map +1 -1
- package/dist/proxy/ProxySessionController.js +767 -260
- package/dist/proxy/ProxySessionController.js.map +1 -1
- package/dist/proxy/SessionOperationQueue.js +14 -0
- package/dist/proxy/SessionOperationQueue.js.map +1 -0
- package/dist/runtime/AcpRuntimeAdapter.js +4 -2
- package/dist/runtime/AcpRuntimeAdapter.js.map +1 -1
- package/dist/state/StateStore.js +22 -0
- package/dist/state/StateStore.js.map +1 -1
- package/dist/state/TurnPreviewJournal.js +19 -7
- package/dist/state/TurnPreviewJournal.js.map +1 -1
- package/dist/state/migrations.js +6 -0
- package/dist/state/migrations.js.map +1 -1
- package/dist/supervision/SafeRestartNotifier.js +1 -0
- package/dist/supervision/SafeRestartNotifier.js.map +1 -1
- package/dist/supervision/SafeRestartScheduler.js +19 -6
- package/dist/supervision/SafeRestartScheduler.js.map +1 -1
- package/dist/terminal/TerminalCards.js +13 -0
- package/dist/terminal/TerminalCards.js.map +1 -0
- package/dist/terminal/TerminalLinks.js +76 -0
- package/dist/terminal/TerminalLinks.js.map +1 -0
- package/dist/terminal/TerminalPage.js +212 -0
- package/dist/terminal/TerminalPage.js.map +1 -0
- package/dist/terminal/TerminalProcess.js +71 -0
- package/dist/terminal/TerminalProcess.js.map +1 -0
- package/dist/terminal/TerminalServer.js +639 -0
- package/dist/terminal/TerminalServer.js.map +1 -0
- package/docs/technical-reference.md +53 -3
- package/docs/technical-reference.zh.md +52 -2
- package/npm-shrinkwrap.json +55 -5
- package/package.json +11 -4
- package/skills/agent-bot/SKILL.md +15 -2
- package/src/cli/controlProtocol.ts +2 -1
- package/src/cli/serverStatus.ts +1 -0
- package/src/cli.ts +6 -1
- package/src/codex/AppServerPermissions.ts +39 -0
- package/src/codex/CodexLocalActivityDetector.ts +34 -4
- package/src/codex/CodexRuntime.ts +243 -139
- package/src/codex/ProviderSwitch.ts +11 -12
- package/src/codex/ThreadWriterProcess.ts +17 -9
- package/src/config/AgentExecutionDefaultsStore.ts +2 -0
- package/src/config/loadConfig.ts +4 -0
- package/src/config/schema.ts +5 -1
- package/src/feishu/CardRenderer.ts +159 -72
- package/src/feishu/FeishuConnector.ts +1 -0
- package/src/feishu/FeishuTurnPresenter.ts +108 -16
- package/src/feishu/types.ts +1 -0
- package/src/index.ts +44 -7
- package/src/local-files/CsvPreview.ts +132 -0
- package/src/local-files/LocalFileViewerServer.ts +102 -15
- package/src/local-files/TurnPreviewPage.ts +131 -13
- package/src/presentation/TurnStateReducer.ts +87 -7
- package/src/presentation/turnViewTypes.ts +9 -0
- package/src/proxy/ProxySessionController.ts +762 -259
- package/src/proxy/SessionOperationQueue.ts +13 -0
- package/src/runtime/AcpRuntimeAdapter.ts +5 -3
- package/src/runtime/types.ts +10 -3
- package/src/state/StateStore.ts +38 -1
- package/src/state/TurnPreviewJournal.ts +19 -7
- package/src/state/migrations.ts +6 -0
- package/src/supervision/SafeRestartNotifier.ts +1 -0
- package/src/supervision/SafeRestartScheduler.ts +18 -6
- package/src/terminal/TerminalCards.ts +18 -0
- package/src/terminal/TerminalLinks.ts +61 -0
- package/src/terminal/TerminalPage.ts +213 -0
- package/src/terminal/TerminalProcess.ts +71 -0
- package/src/terminal/TerminalServer.ts +513 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AgentEvent, RemoteTurnDetails, ToolState } from "../runtime/types.js";
|
|
1
|
+
import type { AgentEvent, ApprovalDecision, ApprovalRequest, RemoteTurnDetails, ToolState } from "../runtime/types.js";
|
|
2
2
|
import { appendGeneratedImageMarkdown } from "../utils/generatedImageMarkdown.js";
|
|
3
3
|
import type { MessageReplyTarget } from "../feishu/types.js";
|
|
4
4
|
import { formatStorageSize } from "../utils/formatStorageSize.js";
|
|
@@ -113,6 +113,13 @@ export function reduceTurnEvent(state: TurnViewState, event: AgentEvent, complet
|
|
|
113
113
|
if (event.type === "turn_completed") next.finalResponse = event.finalResponse;
|
|
114
114
|
if (event.type === "agent_text_delta") next.assistantText = state.assistantText + event.text;
|
|
115
115
|
if (event.type === "plan_updated") next.plan = event.steps;
|
|
116
|
+
if (event.type === "approval_requested" || event.type === "approval_resolved") {
|
|
117
|
+
const request = event.type === "approval_requested" ? event.request
|
|
118
|
+
: state.approval?.id === event.requestId ? state.approval : undefined;
|
|
119
|
+
if (request) next.activities = next.activities.map((a) => a.id === approvalActivityId(event.turnId, request.id) && a.kind === "assistant"
|
|
120
|
+
? { ...a, text: approvalHistoryText(request, event.type === "approval_resolved" ? event.decision : undefined,
|
|
121
|
+
event.type === "approval_resolved" && event.automatic) } : a);
|
|
122
|
+
}
|
|
116
123
|
if (event.type === "progress") {
|
|
117
124
|
const id = event.activityId ?? "progress";
|
|
118
125
|
const old = state.activities.find((a) => a.id === id);
|
|
@@ -162,6 +169,7 @@ function reduceEvent(state: TurnViewState, event: AgentEvent): TurnViewState {
|
|
|
162
169
|
return {
|
|
163
170
|
...state,
|
|
164
171
|
totalTokens: (state.totalTokens ?? 0) + delta,
|
|
172
|
+
...countModelCall(state, event),
|
|
165
173
|
tokenUsageCumulative: Math.max(previousCumulative ?? 0, cumulativeTokens),
|
|
166
174
|
totalTokensIncludingCache: total.value,
|
|
167
175
|
tokenUsageTotalCumulative: total.cumulative,
|
|
@@ -304,7 +312,7 @@ function reduceEvent(state: TurnViewState, event: AgentEvent): TurnViewState {
|
|
|
304
312
|
return {
|
|
305
313
|
...state,
|
|
306
314
|
...tracking,
|
|
307
|
-
status: state.approval ? "waiting_for_approval" : "tool_running",
|
|
315
|
+
status: state.approval && !state.approval.automatic ? "waiting_for_approval" : "tool_running",
|
|
308
316
|
activeTool: bounded,
|
|
309
317
|
activities: activityUpdate.activities,
|
|
310
318
|
activitiesTruncated: state.activitiesTruncated || activityUpdate.truncated,
|
|
@@ -316,10 +324,21 @@ function reduceEvent(state: TurnViewState, event: AgentEvent): TurnViewState {
|
|
|
316
324
|
case "tool_output_delta":
|
|
317
325
|
return reduceToolOutputDelta(state, event.toolId, event.delta);
|
|
318
326
|
case "approval_requested":
|
|
319
|
-
return { ...state, status: "waiting_for_approval", approval: event.request
|
|
327
|
+
return { ...state, status: event.request.automatic ? state.activeTool ? "tool_running" : "running" : "waiting_for_approval", approval: event.request,
|
|
328
|
+
activities: [...state.activities.filter((a) => a.id !== approvalActivityId(event.turnId, event.request.id)), {
|
|
329
|
+
kind: "assistant", id: approvalActivityId(event.turnId, event.request.id), text: bound(approvalHistoryText(event.request)),
|
|
330
|
+
}],
|
|
331
|
+
};
|
|
320
332
|
case "approval_resolved":
|
|
321
333
|
if (state.approval?.id !== event.requestId) return state;
|
|
322
|
-
return {
|
|
334
|
+
return {
|
|
335
|
+
...state, status: state.activeTool ? "tool_running" : "running", approval: undefined,
|
|
336
|
+
activities: upsertActivity(state.activities,
|
|
337
|
+
state.activities.findIndex((a) => a.id === approvalActivityId(event.turnId, event.requestId)), {
|
|
338
|
+
kind: "assistant", id: approvalActivityId(event.turnId, event.requestId),
|
|
339
|
+
text: bound(approvalHistoryText(state.approval, event.decision, event.automatic)),
|
|
340
|
+
}).activities,
|
|
341
|
+
};
|
|
323
342
|
case "turn_completed": {
|
|
324
343
|
const durationMs = Math.max(0, event.durationMs ?? Date.now() - state.startedAt);
|
|
325
344
|
return {
|
|
@@ -362,6 +381,27 @@ function reduceEvent(state: TurnViewState, event: AgentEvent): TurnViewState {
|
|
|
362
381
|
}
|
|
363
382
|
}
|
|
364
383
|
|
|
384
|
+
export function approvalActivityId(turnId: string, requestId: string): string {
|
|
385
|
+
return "approval:" + turnId + ":" + requestId;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
export function continueTurnView(state: TurnViewState, turnId: string, startedAt: number): TurnViewState {
|
|
389
|
+
return { ...state, turnId, previewTurnId: state.previewTurnId ?? state.turnId,
|
|
390
|
+
continuedFromTurnId: state.turnId, continuedToTurnId: undefined, segmentStartedAt: startedAt,
|
|
391
|
+
status: "running", completedAt: undefined, durationMs: undefined, finalResponse: undefined,
|
|
392
|
+
error: undefined, approval: undefined, activeTool: undefined, assistantText: "", progressText: undefined };
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
function approvalHistoryText(request: ApprovalRequest, decision?: ApprovalDecision, automatic = false): string {
|
|
396
|
+
const labels = { accept: "允许一次", acceptForSession: "本会话允许", decline: "拒绝", cancel: "取消请求" };
|
|
397
|
+
const choice = decision ? request.options.find((option) => option.id === decision)?.label ?? labels[decision] : undefined;
|
|
398
|
+
const heading = choice ? automatic ? "自动同意(auto)" : "用户选择:" + choice
|
|
399
|
+
: request.automatic ? "正在自动同意(auto)" : "等待选择";
|
|
400
|
+
return ["**审批请求 · " + heading + "**", request.title, request.reason,
|
|
401
|
+
request.command ? "~~~\n" + request.command + "\n~~~" : undefined,
|
|
402
|
+
].filter(Boolean).join("\n\n");
|
|
403
|
+
}
|
|
404
|
+
|
|
365
405
|
export function appendSteerMessage(state: TurnViewState, id: string, text: string, localImagePaths?: string[]): TurnViewState {
|
|
366
406
|
const normalized = text.trim();
|
|
367
407
|
if (!normalized && !localImagePaths?.length) return state;
|
|
@@ -441,7 +481,7 @@ function reduceToolUpdate(state: TurnViewState, tool: ToolState, fullOutput?: st
|
|
|
441
481
|
...tracking,
|
|
442
482
|
fullToolOutputs,
|
|
443
483
|
fullToolErrors,
|
|
444
|
-
status: state.approval ? "waiting_for_approval" : "tool_running",
|
|
484
|
+
status: state.approval && !state.approval.automatic ? "waiting_for_approval" : "tool_running",
|
|
445
485
|
activeTool: bounded,
|
|
446
486
|
activities: activityUpdate.activities,
|
|
447
487
|
activitiesTruncated: state.activitiesTruncated || activityUpdate.truncated,
|
|
@@ -457,7 +497,7 @@ function reduceToolUpdate(state: TurnViewState, tool: ToolState, fullOutput?: st
|
|
|
457
497
|
...tracking,
|
|
458
498
|
fullToolOutputs,
|
|
459
499
|
fullToolErrors,
|
|
460
|
-
status: state.approval ? "waiting_for_approval" : activeTool ? "tool_running" : "running",
|
|
500
|
+
status: state.approval && !state.approval.automatic ? "waiting_for_approval" : activeTool ? "tool_running" : "running",
|
|
461
501
|
activeTool,
|
|
462
502
|
activities: activityUpdate.activities,
|
|
463
503
|
activitiesTruncated: state.activitiesTruncated || activityUpdate.truncated,
|
|
@@ -472,7 +512,7 @@ function reduceToolUpdate(state: TurnViewState, tool: ToolState, fullOutput?: st
|
|
|
472
512
|
...tracking,
|
|
473
513
|
fullToolOutputs,
|
|
474
514
|
fullToolErrors,
|
|
475
|
-
status: state.approval ? "waiting_for_approval" : activeTool ? "tool_running" : "running",
|
|
515
|
+
status: state.approval && !state.approval.automatic ? "waiting_for_approval" : activeTool ? "tool_running" : "running",
|
|
476
516
|
activeTool,
|
|
477
517
|
activities: activityUpdate.activities,
|
|
478
518
|
activitiesTruncated: state.activitiesTruncated || activityUpdate.truncated,
|
|
@@ -609,6 +649,46 @@ function bound(value: string): string {
|
|
|
609
649
|
return `${value.slice(0, MAX_TEXT - 1)}…`;
|
|
610
650
|
}
|
|
611
651
|
|
|
652
|
+
function countModelCall(
|
|
653
|
+
state: TurnViewState,
|
|
654
|
+
event: Extract<AgentEvent, { type: "token_usage_updated" }>,
|
|
655
|
+
): Pick<TurnViewState, "modelCallCount" | "modelCallTokenBaseline"> {
|
|
656
|
+
// A pre-existing snapshot without a counter cannot provide a complete turn count.
|
|
657
|
+
if (state.modelCallCount === undefined && state.modelCallTokenBaseline === undefined
|
|
658
|
+
&& state.tokenUsageCumulative !== undefined) return {};
|
|
659
|
+
const nonCached = reportedUsage(event.lastTokens, event.cumulativeTokens);
|
|
660
|
+
const total = reportedUsage(event.lastTotalTokens, event.cumulativeTotalTokens);
|
|
661
|
+
if (!nonCached && !total) return { modelCallTokenBaseline: state.modelCallTokenBaseline ?? {} };
|
|
662
|
+
const previous = state.modelCallTokenBaseline;
|
|
663
|
+
const usage = total ?? nonCached!;
|
|
664
|
+
const staleNonCached = nonCached !== undefined && previous?.nonCached !== undefined
|
|
665
|
+
&& nonCached.cumulative < previous.nonCached;
|
|
666
|
+
const nonCachedGrew = nonCached !== undefined && previous?.nonCached !== undefined
|
|
667
|
+
&& nonCached.cumulative > previous.nonCached;
|
|
668
|
+
const grew = total && previous?.total !== undefined && !previous.totalNeedsRebase
|
|
669
|
+
? total.cumulative > previous.total
|
|
670
|
+
: nonCached && previous?.nonCached !== undefined
|
|
671
|
+
? nonCachedGrew
|
|
672
|
+
: previous?.total === undefined && previous?.nonCached === undefined
|
|
673
|
+
&& usage.last > 0 && usage.cumulative > 0;
|
|
674
|
+
return {
|
|
675
|
+
modelCallCount: (state.modelCallCount ?? 0) + (grew ? 1 : 0),
|
|
676
|
+
modelCallTokenBaseline: {
|
|
677
|
+
nonCached: nonCached ? Math.max(previous?.nonCached ?? 0, nonCached.cumulative) : previous?.nonCached,
|
|
678
|
+
total: total ? Math.max(previous?.total ?? 0, total.cumulative) : previous?.total,
|
|
679
|
+
// After a legacy-only update, rebase totals before using them again; keep
|
|
680
|
+
// their high-water mark so stale reports cannot lower the baseline.
|
|
681
|
+
totalNeedsRebase: total && !staleNonCached ? false : nonCachedGrew || previous?.totalNeedsRebase,
|
|
682
|
+
},
|
|
683
|
+
};
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
function reportedUsage(last: number | undefined, cumulative: number | undefined): { last: number; cumulative: number } | undefined {
|
|
687
|
+
if (last === undefined || cumulative === undefined || !Number.isFinite(last) || !Number.isFinite(cumulative)
|
|
688
|
+
|| last < 0 || cumulative < 0) return undefined;
|
|
689
|
+
return { last: normalizeTokenCount(last), cumulative: normalizeTokenCount(cumulative) };
|
|
690
|
+
}
|
|
691
|
+
|
|
612
692
|
function accumulateReportedTokens(
|
|
613
693
|
last: number | undefined,
|
|
614
694
|
cumulative: number | undefined,
|
|
@@ -36,6 +36,11 @@ export interface TurnViewState {
|
|
|
36
36
|
previewJournal?: boolean;
|
|
37
37
|
/** Byte cursor for the on-demand preview, never needed for recovery. */
|
|
38
38
|
previewCursor?: number;
|
|
39
|
+
/** Shared presentation journal across a plan/implementation handoff. */
|
|
40
|
+
previewTurnId?: string;
|
|
41
|
+
continuedFromTurnId?: string;
|
|
42
|
+
continuedToTurnId?: string;
|
|
43
|
+
segmentStartedAt?: number;
|
|
39
44
|
sessionId: string;
|
|
40
45
|
turnId: string;
|
|
41
46
|
agentLabel?: string;
|
|
@@ -56,6 +61,10 @@ export interface TurnViewState {
|
|
|
56
61
|
cachedInputTokens?: number;
|
|
57
62
|
tokenUsageTotalCumulative?: number;
|
|
58
63
|
tokenUsageCachedCumulative?: number;
|
|
64
|
+
/** Effective token-usage updates observed for this turn. */
|
|
65
|
+
modelCallCount?: number;
|
|
66
|
+
/** Independent high-water marks; token breakdowns may disappear in partial updates. */
|
|
67
|
+
modelCallTokenBaseline?: { nonCached?: number; total?: number; totalNeedsRebase?: boolean };
|
|
59
68
|
contextCompactionStatus?: "running" | "completed";
|
|
60
69
|
contextCompactionCount?: number;
|
|
61
70
|
contextCompactionId?: string;
|