@keyou007/agent-bot 0.1.17-alpha.2 → 0.1.17
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 +4 -0
- package/dist/feishu/CardRenderer.js +6 -16
- package/dist/feishu/CardRenderer.js.map +1 -1
- package/dist/local-files/LocalFileViewerServer.js +416 -58
- package/dist/local-files/LocalFileViewerServer.js.map +1 -1
- package/dist/proxy/ProxySessionController.js +39 -6
- package/dist/proxy/ProxySessionController.js.map +1 -1
- package/dist/startup/StartupNotifier.js +7 -4
- package/dist/startup/StartupNotifier.js.map +1 -1
- package/docs/technical-reference.md +2 -0
- package/docs/technical-reference.zh.md +2 -0
- package/npm-shrinkwrap.json +12 -2
- package/package.json +2 -1
- package/src/feishu/CardRenderer.ts +6 -22
- package/src/local-files/LocalFileViewerServer.ts +428 -60
- package/src/proxy/ProxySessionController.ts +43 -5
- package/src/startup/StartupNotifier.ts +9 -4
|
@@ -125,6 +125,7 @@ const SESSION_PROMPT_PREVIEW_LENGTH = 50;
|
|
|
125
125
|
const DIRECTORY_PAGE_SIZE = 15;
|
|
126
126
|
const RESET_HISTORY_PAGE_SIZE = 10;
|
|
127
127
|
const MAX_LLM_TURN_RETRIES = 3;
|
|
128
|
+
const QUEUED_PROMPT_RETRY_DELAY_MS = 5_000;
|
|
128
129
|
const RECOVERY_ACTIVITY_WINDOW_MS = 10 * 60 * 1_000;
|
|
129
130
|
const RECOVERY_HEARTBEAT_INTERVAL_MS = 60 * 1_000;
|
|
130
131
|
const SHELL_COMMAND_JOB_POLL_INTERVAL_MS = 1_000;
|
|
@@ -132,7 +133,7 @@ const SHELL_COMMAND_JOB_RELAUNCH_DELAY_MS = 5_000;
|
|
|
132
133
|
const FORWARD_ATTACHMENT_WINDOW_MS = 800;
|
|
133
134
|
const DEFAULT_MERGED_FORWARD_INSTRUCTION = "请参考以下内容回复用户";
|
|
134
135
|
const DEFAULT_REFERENCED_MESSAGE_INSTRUCTION = "请参考引用消息回复用户";
|
|
135
|
-
const TURN_STOP_REQUESTED_MESSAGE = "
|
|
136
|
+
const TURN_STOP_REQUESTED_MESSAGE = "已发送停止信号,任务会自动停止。";
|
|
136
137
|
const REMOTE_SESSION_REFERENCE_PREFIX = "agent-runtime:";
|
|
137
138
|
const WINDOWS_DRIVES_DIRECTORY = "agentbot://windows-drives";
|
|
138
139
|
const IMAGE_FILE_EXTENSIONS = new Set([
|
|
@@ -428,6 +429,7 @@ export class ProxySessionController {
|
|
|
428
429
|
private readonly threadInitializations = new Map<string, Promise<void>>();
|
|
429
430
|
private readonly llmRetryingSessions = new Set<string>();
|
|
430
431
|
private readonly retriedFailureTurnIds = new Set<string>();
|
|
432
|
+
private readonly queuedPromptRetryTimers = new Map<string, NodeJS.Timeout>();
|
|
431
433
|
private readonly recoveryRetryTimers = new Map<string, NodeJS.Timeout>();
|
|
432
434
|
private readonly pendingMergedForwards = new Map<string, PendingForwardAttachment>();
|
|
433
435
|
private readonly pendingResourceForwards = new Map<string, PendingForwardAttachment>();
|
|
@@ -1097,6 +1099,8 @@ export class ProxySessionController {
|
|
|
1097
1099
|
for (const pending of this.pendingResourceForwards.values()) pending.resolveAttachment(undefined);
|
|
1098
1100
|
this.pendingResourceForwards.clear();
|
|
1099
1101
|
this.relatedReactionMessageIds.clear();
|
|
1102
|
+
for (const timer of this.queuedPromptRetryTimers.values()) clearTimeout(timer);
|
|
1103
|
+
this.queuedPromptRetryTimers.clear();
|
|
1100
1104
|
for (const timer of this.recoveryRetryTimers.values()) clearTimeout(timer);
|
|
1101
1105
|
this.recoveryRetryTimers.clear();
|
|
1102
1106
|
for (const [jobId] of this.shellCommandJobMonitors) this.stopShellCommandJobMonitor(jobId);
|
|
@@ -3993,6 +3997,11 @@ export class ProxySessionController {
|
|
|
3993
3997
|
}
|
|
3994
3998
|
|
|
3995
3999
|
private scheduleNextQueuedPrompt(sessionId: string): Promise<void> {
|
|
4000
|
+
const retryTimer = this.queuedPromptRetryTimers.get(sessionId);
|
|
4001
|
+
if (retryTimer) {
|
|
4002
|
+
clearTimeout(retryTimer);
|
|
4003
|
+
this.queuedPromptRetryTimers.delete(sessionId);
|
|
4004
|
+
}
|
|
3996
4005
|
const previous = this.queuedPromptStarts.get(sessionId) ?? Promise.resolve();
|
|
3997
4006
|
const next = previous.catch(() => undefined).then(() => this.startNextQueuedPromptIfIdle(sessionId));
|
|
3998
4007
|
this.queuedPromptStarts.set(sessionId, next);
|
|
@@ -4001,6 +4010,23 @@ export class ProxySessionController {
|
|
|
4001
4010
|
});
|
|
4002
4011
|
}
|
|
4003
4012
|
|
|
4013
|
+
private scheduleQueuedPromptRetry(sessionId: string): void {
|
|
4014
|
+
if (this.queuedPromptRetryTimers.has(sessionId)) return;
|
|
4015
|
+
if (this.store.countQueuedPrompts(sessionId) === 0) return;
|
|
4016
|
+
const timer = setTimeout(() => {
|
|
4017
|
+
this.queuedPromptRetryTimers.delete(sessionId);
|
|
4018
|
+
void this.scheduleNextQueuedPrompt(sessionId).catch((error: unknown) => {
|
|
4019
|
+
this.logger.warn(
|
|
4020
|
+
{ error, errorMessage: runtimeErrorMessage(error), sessionId },
|
|
4021
|
+
"Failed to retry queued prompt start.",
|
|
4022
|
+
);
|
|
4023
|
+
this.scheduleQueuedPromptRetry(sessionId);
|
|
4024
|
+
});
|
|
4025
|
+
}, QUEUED_PROMPT_RETRY_DELAY_MS);
|
|
4026
|
+
timer.unref?.();
|
|
4027
|
+
this.queuedPromptRetryTimers.set(sessionId, timer);
|
|
4028
|
+
}
|
|
4029
|
+
|
|
4004
4030
|
private async startNextQueuedPromptIfIdle(sessionId: string): Promise<void> {
|
|
4005
4031
|
if (this.store.countQueuedPrompts(sessionId) === 0) return;
|
|
4006
4032
|
const baseRecord = this.store.getSession(sessionId);
|
|
@@ -4028,10 +4054,22 @@ export class ProxySessionController {
|
|
|
4028
4054
|
);
|
|
4029
4055
|
if (prompt.messageId) await this.bindMessageReactionToTurn(prompt.messageId, sessionId, turnId);
|
|
4030
4056
|
} catch (error) {
|
|
4031
|
-
this.logger.warn(
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4057
|
+
this.logger.warn(
|
|
4058
|
+
{
|
|
4059
|
+
error,
|
|
4060
|
+
errorMessage: runtimeErrorMessage(error),
|
|
4061
|
+
phase: prompt ? "start" : "preflight",
|
|
4062
|
+
sessionId,
|
|
4063
|
+
},
|
|
4064
|
+
"Failed to start queued prompt.",
|
|
4065
|
+
);
|
|
4066
|
+
if (!prompt) {
|
|
4067
|
+
this.scheduleQueuedPromptRetry(sessionId);
|
|
4068
|
+
return;
|
|
4069
|
+
}
|
|
4070
|
+
if (prompt.messageId) await this.finalizeStandaloneMessageReaction(prompt.messageId, "failed");
|
|
4071
|
+
await this.sendError(prompt.contextKey, error);
|
|
4072
|
+
if (this.store.countQueuedPrompts(sessionId) > 0) {
|
|
4035
4073
|
queueMicrotask(() => void this.scheduleNextQueuedPrompt(sessionId));
|
|
4036
4074
|
}
|
|
4037
4075
|
}
|
|
@@ -48,8 +48,13 @@ export class StartupNotifier {
|
|
|
48
48
|
.filter((chat) => !isThreadContextKey(chat.contextKey))
|
|
49
49
|
.map((chat) => [chat.contextKey, chat]),
|
|
50
50
|
);
|
|
51
|
+
const knownPrivateChats = new Map(
|
|
52
|
+
this.store.listChatContexts("p2p")
|
|
53
|
+
.filter((chat) => !isThreadContextKey(chat.contextKey))
|
|
54
|
+
.map((chat) => [chat.contextKey, chat]),
|
|
55
|
+
);
|
|
51
56
|
const targetsByContext = new Map<string, StartupNotificationTarget>();
|
|
52
|
-
for (const chat of
|
|
57
|
+
for (const chat of knownPrivateChats.values()) {
|
|
53
58
|
targetsByContext.set(chat.contextKey, {
|
|
54
59
|
contextKey: chat.contextKey,
|
|
55
60
|
context: this.store.getUserContext(chat.contextKey),
|
|
@@ -71,10 +76,11 @@ export class StartupNotifier {
|
|
|
71
76
|
if (!contextKey) continue;
|
|
72
77
|
if (isThreadContextKey(contextKey)) {
|
|
73
78
|
const baseContextKey = baseChatContextKey(contextKey);
|
|
74
|
-
|
|
79
|
+
const parentChat = knownGroups.get(baseContextKey) ?? knownPrivateChats.get(baseContextKey);
|
|
80
|
+
if (!parentChat) continue;
|
|
75
81
|
const replyMessageId = target.replyMessageId?.trim();
|
|
76
82
|
if (replyMessageId) {
|
|
77
|
-
if (!explicitBaseContextKeys.has(baseContextKey)) {
|
|
83
|
+
if (parentChat.chatType === "group" && !explicitBaseContextKeys.has(baseContextKey)) {
|
|
78
84
|
targetsByContext.delete(baseContextKey);
|
|
79
85
|
}
|
|
80
86
|
targetsByContext.set(contextKey, {
|
|
@@ -83,7 +89,6 @@ export class StartupNotifier {
|
|
|
83
89
|
context: this.store.getUserContext(contextKey),
|
|
84
90
|
});
|
|
85
91
|
} else {
|
|
86
|
-
const group = knownGroups.get(baseContextKey)!;
|
|
87
92
|
targetsByContext.set(baseContextKey, {
|
|
88
93
|
contextKey: baseContextKey,
|
|
89
94
|
context: this.store.getUserContext(baseContextKey),
|