@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
|
@@ -9,7 +9,7 @@ import type {
|
|
|
9
9
|
RemoteSessionSummary,
|
|
10
10
|
RuntimeGoal,
|
|
11
11
|
} from "../runtime/types.js";
|
|
12
|
-
import type { SessionRecord } from "../state/StateStore.js";
|
|
12
|
+
import type { SessionRecord, PendingProviderSettings } from "../state/StateStore.js";
|
|
13
13
|
import type { ShellCommandResult } from "../utils/executeShellCommand.js";
|
|
14
14
|
|
|
15
15
|
export type ControlRequest =
|
|
@@ -136,6 +136,7 @@ export interface TaskAgentControlData {
|
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
export interface TaskSettingsControlData {
|
|
139
|
+
pendingProvider?: PendingProviderSettings;
|
|
139
140
|
session: SessionRecord;
|
|
140
141
|
providers: ModelProviderOption[];
|
|
141
142
|
models: ModelOption[];
|
package/src/cli/serverStatus.ts
CHANGED
|
@@ -38,6 +38,7 @@ export function formatServerStatus(data: unknown, language: CliLanguage = cliLan
|
|
|
38
38
|
`${cliText("Supervisor: ", "Supervisor:", language)}${value.supervised ? cliText("enabled", "已启用", language) : cliText("disabled", "未启用", language)}`,
|
|
39
39
|
...agents,
|
|
40
40
|
`${cliText("Running tasks: ", "运行中任务:", language)}${activity.runningSessions ?? 0}`,
|
|
41
|
+
...(activity.activeTerminals ? [`${cliText("Active terminals: ", "活动终端:", language)}${activity.activeTerminals}`] : []),
|
|
41
42
|
`${cliText("Pending final deliveries: ", "待发送最终结果:", language)}${activity.pendingFinalDeliveries ?? 0}`,
|
|
42
43
|
`${cliText("Safe restart: ", "安全重启:", language)}${safeRestart}`,
|
|
43
44
|
"",
|
package/src/cli.ts
CHANGED
|
@@ -1832,7 +1832,12 @@ function printTaskSettings(
|
|
|
1832
1832
|
result: TaskSettingsControlData,
|
|
1833
1833
|
setting: "provider" | "model" | "thinking" | "permissions",
|
|
1834
1834
|
): void {
|
|
1835
|
-
const session = result.session;
|
|
1835
|
+
const session = result.pendingProvider?.settings ?? result.session;
|
|
1836
|
+
if (result.pendingProvider) {
|
|
1837
|
+
const status = cliText("Pending Provider switch (after current turn)", "Provider 待切换(本轮结束后生效)");
|
|
1838
|
+
const error = result.pendingProvider.error ? `: ${result.pendingProvider.error}` : "";
|
|
1839
|
+
process.stdout.write(`${status}${error}\n`);
|
|
1840
|
+
}
|
|
1836
1841
|
process.stdout.write(`${cliText("Provider: ", "Provider:")}${session.modelProvider ?? cliText("Agent default", "Agent 默认")}\n`);
|
|
1837
1842
|
process.stdout.write(`${cliText("Model: ", "模型:")}${session.model ?? cliText("default", "默认")}\n`);
|
|
1838
1843
|
process.stdout.write(`${cliText("Thinking: ", "思考强度:")}${session.reasoningEffort ?? cliText("automatic", "自动")}\n`);
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
const workspacePolicySchema = z.object({
|
|
4
|
+
type: z.literal("workspaceWrite"),
|
|
5
|
+
writableRoots: z.array(z.string().min(1)),
|
|
6
|
+
networkAccess: z.boolean(),
|
|
7
|
+
excludeTmpdirEnvVar: z.boolean(),
|
|
8
|
+
excludeSlashTmp: z.boolean(),
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
const workspaceConfigSchema = z.object({
|
|
12
|
+
sandbox_workspace_write: z.object({
|
|
13
|
+
writable_roots: z.array(z.string().min(1)).default([]),
|
|
14
|
+
network_access: z.boolean().default(false),
|
|
15
|
+
exclude_tmpdir_env_var: z.boolean().default(false),
|
|
16
|
+
exclude_slash_tmp: z.boolean().default(false),
|
|
17
|
+
}).nullish(),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
export type WorkspaceSandboxPolicy = z.infer<typeof workspacePolicySchema>;
|
|
21
|
+
export type TurnSandboxPolicy = WorkspaceSandboxPolicy | { type: "dangerFullAccess" };
|
|
22
|
+
|
|
23
|
+
export function workspaceSandboxFromResponse(sandbox: unknown): WorkspaceSandboxPolicy | undefined {
|
|
24
|
+
const parsed = workspacePolicySchema.safeParse(sandbox);
|
|
25
|
+
return parsed.success ? parsed.data : undefined;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function workspaceSandboxFromConfig(config: unknown): WorkspaceSandboxPolicy {
|
|
29
|
+
const parsed = workspaceConfigSchema.safeParse(config);
|
|
30
|
+
if (!parsed.success) throw new Error("App Server 返回了无效的工作区沙箱配置,未启动新轮次。");
|
|
31
|
+
const settings = parsed.data.sandbox_workspace_write;
|
|
32
|
+
return {
|
|
33
|
+
type: "workspaceWrite",
|
|
34
|
+
writableRoots: settings?.writable_roots ?? [],
|
|
35
|
+
networkAccess: settings?.network_access ?? false,
|
|
36
|
+
excludeTmpdirEnvVar: settings?.exclude_tmpdir_env_var ?? false,
|
|
37
|
+
excludeSlashTmp: settings?.exclude_slash_tmp ?? false,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -2,8 +2,10 @@ import { open } from "node:fs/promises";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import Database from "better-sqlite3";
|
|
4
4
|
import type { PermissionMode } from "../runtime/types.js";
|
|
5
|
+
import { SystemThreadWriterProcessController, threadWriterLockPath } from "./ThreadWriterProcess.js";
|
|
5
6
|
|
|
6
7
|
const READ_CHUNK_SIZE = 64 * 1024;
|
|
8
|
+
const WRITER_CHECK_CACHE_MS = 5_000;
|
|
7
9
|
const TASK_STARTED = Buffer.from('"type":"task_started"');
|
|
8
10
|
const TASK_COMPLETE = Buffer.from('"type":"task_complete"');
|
|
9
11
|
const TURN_ABORTED = Buffer.from('"type":"turn_aborted"');
|
|
@@ -46,7 +48,14 @@ export interface CodexLocalThreadSettings {
|
|
|
46
48
|
*/
|
|
47
49
|
export class CodexLocalActivityDetector {
|
|
48
50
|
private readonly rollouts = new Map<string, RolloutState>();
|
|
49
|
-
|
|
51
|
+
private readonly writerChecks = new Map<string, { expiresAt: number; result: Promise<boolean> }>();
|
|
52
|
+
constructor(
|
|
53
|
+
private readonly codexHome: string,
|
|
54
|
+
private readonly hasWriter: (threadId: string) => Promise<boolean> = async (threadId) => {
|
|
55
|
+
const lockPath = threadWriterLockPath(codexHome, threadId);
|
|
56
|
+
return Boolean(lockPath && (await new SystemThreadWriterProcessController().inspect(lockPath)).length > 0);
|
|
57
|
+
},
|
|
58
|
+
) {}
|
|
50
59
|
|
|
51
60
|
async activeThreadIds(threadIds: string[]): Promise<Set<string>> {
|
|
52
61
|
return new Set((await this.activeThreads(threadIds)).keys());
|
|
@@ -74,13 +83,34 @@ export class CodexLocalActivityDetector {
|
|
|
74
83
|
}
|
|
75
84
|
|
|
76
85
|
const active = new Map<string, string | undefined>();
|
|
77
|
-
for (
|
|
78
|
-
|
|
79
|
-
|
|
86
|
+
for (let index = 0; index < rows.length; index += 4) {
|
|
87
|
+
await Promise.all(rows.slice(index, index + 4).map(async (row) => {
|
|
88
|
+
const task = await latestTask(row.rollout_path, this.rollouts);
|
|
89
|
+
// An unpaired start survives a crash. It is not evidence of a live process.
|
|
90
|
+
if (task.active && await this.hasLiveWriter(row.id)) active.set(row.id, task.turnId);
|
|
91
|
+
}));
|
|
80
92
|
}
|
|
81
93
|
return active;
|
|
82
94
|
}
|
|
83
95
|
|
|
96
|
+
private async hasLiveWriter(threadId: string): Promise<boolean> {
|
|
97
|
+
const cached = this.writerChecks.get(threadId);
|
|
98
|
+
if (cached && cached.expiresAt > Date.now()) return cached.result;
|
|
99
|
+
const result = this.hasWriter(threadId).catch((error: unknown) => {
|
|
100
|
+
throw new Error("无法确认任务的写入进程是否仍在运行,请稍后重试。", { cause: error });
|
|
101
|
+
});
|
|
102
|
+
const entry = { expiresAt: Date.now() + WRITER_CHECK_CACHE_MS, result };
|
|
103
|
+
this.writerChecks.delete(threadId);
|
|
104
|
+
this.writerChecks.set(threadId, entry);
|
|
105
|
+
if (this.writerChecks.size > 512) this.writerChecks.delete(this.writerChecks.keys().next().value!);
|
|
106
|
+
try {
|
|
107
|
+
return await result;
|
|
108
|
+
} catch (error) {
|
|
109
|
+
if (this.writerChecks.get(threadId) === entry) this.writerChecks.delete(threadId);
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
84
114
|
async threadSettings(threadIds: string[]): Promise<Map<string, CodexLocalThreadSettings>> {
|
|
85
115
|
const ids = [...new Set(threadIds.filter(Boolean))];
|
|
86
116
|
if (ids.length === 0) return new Map();
|