@keyou007/agent-bot 0.1.16 → 0.1.17-alpha.1
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 +14 -0
- package/README.md +4 -2
- package/README.zh.md +4 -2
- package/config.example.yaml +8 -0
- package/dist/cli/help.js +4 -4
- package/dist/cli/taskTarget.js +7 -0
- package/dist/cli/taskTarget.js.map +1 -1
- package/dist/cli.js +12 -12
- package/dist/cli.js.map +1 -1
- package/dist/codex/CodexProcessManager.js +2 -1
- package/dist/codex/CodexProcessManager.js.map +1 -1
- package/dist/codex/CodexRuntime.js +62 -14
- package/dist/codex/CodexRuntime.js.map +1 -1
- package/dist/config/AgentExecutionDefaultsStore.js +71 -0
- package/dist/config/AgentExecutionDefaultsStore.js.map +1 -0
- package/dist/config/loadConfig.js +8 -0
- package/dist/config/loadConfig.js.map +1 -1
- package/dist/config/schema.js +7 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/feishu/CardRenderer.js +29 -27
- package/dist/feishu/CardRenderer.js.map +1 -1
- package/dist/feishu/FeishuConnector.js +61 -5
- package/dist/feishu/FeishuConnector.js.map +1 -1
- package/dist/feishu/FeishuTurnPresenter.js +2 -2
- package/dist/feishu/FeishuTurnPresenter.js.map +1 -1
- package/dist/index.js +17 -2
- package/dist/index.js.map +1 -1
- package/dist/proxy/ProxySessionController.js +255 -30
- package/dist/proxy/ProxySessionController.js.map +1 -1
- package/dist/state/StateStore.js +62 -9
- package/dist/state/StateStore.js.map +1 -1
- package/dist/supervision/restartNotificationTarget.js +9 -0
- package/dist/supervision/restartNotificationTarget.js.map +1 -0
- package/dist/utils/spawnCommand.js +2 -1
- package/dist/utils/spawnCommand.js.map +1 -1
- package/docs/technical-reference.md +7 -3
- package/docs/technical-reference.zh.md +7 -3
- package/npm-shrinkwrap.json +9 -9
- package/package.json +2 -2
- package/skills/agent-bot/SKILL.md +3 -1
- package/src/cli/help.ts +4 -4
- package/src/cli/taskTarget.ts +11 -0
- package/src/cli.ts +16 -20
- package/src/codex/CodexProcessManager.ts +3 -1
- package/src/codex/CodexRuntime.ts +63 -12
- package/src/config/AgentExecutionDefaultsStore.ts +71 -0
- package/src/config/loadConfig.ts +8 -0
- package/src/config/schema.ts +13 -1
- package/src/feishu/CardRenderer.ts +30 -22
- package/src/feishu/FeishuConnector.ts +70 -5
- package/src/feishu/FeishuTurnPresenter.ts +2 -2
- package/src/index.ts +17 -2
- package/src/proxy/ProxySessionController.ts +330 -40
- package/src/runtime/types.ts +8 -0
- package/src/state/StateStore.ts +100 -9
- package/src/supervision/restartNotificationTarget.ts +12 -0
- package/src/utils/spawnCommand.ts +2 -0
package/src/state/StateStore.ts
CHANGED
|
@@ -95,6 +95,23 @@ export interface CompletedTurnSnapshotRecord {
|
|
|
95
95
|
updatedAt: string;
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
export interface ImportedCompletedTurnRecord {
|
|
99
|
+
turnId: string;
|
|
100
|
+
snapshot: unknown;
|
|
101
|
+
updatedAt: string;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export interface ForkHistorySourceRecord {
|
|
105
|
+
sourceLocalSessionId?: string;
|
|
106
|
+
sourceRemoteSessionId?: string;
|
|
107
|
+
sourceTurnId: string;
|
|
108
|
+
sourceTurnPrompt?: string;
|
|
109
|
+
sourceTurnStartedAt?: number;
|
|
110
|
+
sourceTurnCompletedAt?: number;
|
|
111
|
+
sourceTurnHistoryCount?: number;
|
|
112
|
+
createdAt: string;
|
|
113
|
+
}
|
|
114
|
+
|
|
98
115
|
export interface QueuedPromptRecord {
|
|
99
116
|
promptId: string;
|
|
100
117
|
localSessionId: string;
|
|
@@ -1091,6 +1108,45 @@ export class StateStore {
|
|
|
1091
1108
|
`).run(turnId, localSessionId, parentTurnId ?? null, new Date().toISOString());
|
|
1092
1109
|
}
|
|
1093
1110
|
|
|
1111
|
+
importCompletedTurnHistory(input: {
|
|
1112
|
+
localSessionId: string;
|
|
1113
|
+
contextKey: string;
|
|
1114
|
+
agentName: string;
|
|
1115
|
+
remoteSessionId: string;
|
|
1116
|
+
turns: ImportedCompletedTurnRecord[];
|
|
1117
|
+
}): void {
|
|
1118
|
+
const importHistory = this.db.transaction(() => {
|
|
1119
|
+
let parentTurnId: string | undefined;
|
|
1120
|
+
for (const turn of input.turns) {
|
|
1121
|
+
this.db.prepare(`
|
|
1122
|
+
INSERT OR IGNORE INTO turn_snapshots (
|
|
1123
|
+
turn_id, local_session_id, context_key, snapshot_json, updated_at
|
|
1124
|
+
) VALUES (?, ?, ?, ?, ?)
|
|
1125
|
+
`).run(
|
|
1126
|
+
turn.turnId,
|
|
1127
|
+
input.localSessionId,
|
|
1128
|
+
input.contextKey,
|
|
1129
|
+
JSON.stringify(turn.snapshot),
|
|
1130
|
+
turn.updatedAt,
|
|
1131
|
+
);
|
|
1132
|
+
this.db.prepare(`
|
|
1133
|
+
INSERT OR IGNORE INTO turn_runtime_origins (
|
|
1134
|
+
turn_id, local_session_id, agent_name, remote_session_id, created_at
|
|
1135
|
+
) VALUES (?, ?, ?, ?, ?)
|
|
1136
|
+
`).run(
|
|
1137
|
+
turn.turnId,
|
|
1138
|
+
input.localSessionId,
|
|
1139
|
+
input.agentName,
|
|
1140
|
+
input.remoteSessionId,
|
|
1141
|
+
turn.updatedAt,
|
|
1142
|
+
);
|
|
1143
|
+
this.saveTurnParent(turn.turnId, input.localSessionId, parentTurnId);
|
|
1144
|
+
parentTurnId = turn.turnId;
|
|
1145
|
+
}
|
|
1146
|
+
});
|
|
1147
|
+
importHistory();
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1094
1150
|
getTurnParent(turnId: string, localSessionId: string): string | undefined {
|
|
1095
1151
|
const row = this.db.prepare(`
|
|
1096
1152
|
SELECT parent_turn_id
|
|
@@ -1219,6 +1275,41 @@ export class StateStore {
|
|
|
1219
1275
|
return [...records.values()].sort(compareCompletedTurnSnapshots);
|
|
1220
1276
|
}
|
|
1221
1277
|
|
|
1278
|
+
getForkHistorySource(localSessionId: string): ForkHistorySourceRecord | undefined {
|
|
1279
|
+
const row = this.db.prepare(`
|
|
1280
|
+
SELECT payload_json, created_at
|
|
1281
|
+
FROM audit_events
|
|
1282
|
+
WHERE event_type IN ('session_forked', 'thread_forked')
|
|
1283
|
+
AND json_extract(payload_json, '$.forkedLocalSessionId') = ?
|
|
1284
|
+
ORDER BY id DESC
|
|
1285
|
+
LIMIT 1
|
|
1286
|
+
`).get(localSessionId) as { payload_json: string; created_at: string } | undefined;
|
|
1287
|
+
if (!row) return undefined;
|
|
1288
|
+
const payload = JSON.parse(row.payload_json) as Record<string, unknown>;
|
|
1289
|
+
const sourceTurnId = stringValue(payload.sourceTurnId);
|
|
1290
|
+
if (!sourceTurnId) return undefined;
|
|
1291
|
+
return {
|
|
1292
|
+
sourceLocalSessionId: stringValue(payload.sourceLocalSessionId),
|
|
1293
|
+
sourceRemoteSessionId: stringValue(payload.sourceRemoteSessionId),
|
|
1294
|
+
sourceTurnId,
|
|
1295
|
+
sourceTurnPrompt: stringValue(payload.sourceTurnPrompt),
|
|
1296
|
+
sourceTurnStartedAt: numberValue(payload.sourceTurnStartedAt),
|
|
1297
|
+
sourceTurnCompletedAt: numberValue(payload.sourceTurnCompletedAt),
|
|
1298
|
+
sourceTurnHistoryCount: numberValue(payload.sourceTurnHistoryCount),
|
|
1299
|
+
createdAt: row.created_at,
|
|
1300
|
+
};
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
hasImportedForkTurnHistory(localSessionId: string): boolean {
|
|
1304
|
+
return Boolean(this.db.prepare(`
|
|
1305
|
+
SELECT 1
|
|
1306
|
+
FROM audit_events
|
|
1307
|
+
WHERE event_type = 'fork_turn_history_imported'
|
|
1308
|
+
AND json_extract(payload_json, '$.forkedLocalSessionId') = ?
|
|
1309
|
+
LIMIT 1
|
|
1310
|
+
`).get(localSessionId));
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1222
1313
|
private listCompletedTurnGraphRows(localSessionId: string): CompletedTurnSnapshotRecord[] {
|
|
1223
1314
|
const rows = this.db.prepare(`
|
|
1224
1315
|
SELECT ts.turn_id, tpl.parent_turn_id, ts.snapshot_json, ts.updated_at
|
|
@@ -1260,15 +1351,7 @@ export class StateStore {
|
|
|
1260
1351
|
}
|
|
1261
1352
|
|
|
1262
1353
|
private findForkSourceTurnId(localSessionId: string): string | undefined {
|
|
1263
|
-
|
|
1264
|
-
SELECT json_extract(payload_json, '$.sourceTurnId') AS source_turn_id
|
|
1265
|
-
FROM audit_events
|
|
1266
|
-
WHERE event_type IN ('session_forked', 'thread_forked')
|
|
1267
|
-
AND json_extract(payload_json, '$.forkedLocalSessionId') = ?
|
|
1268
|
-
ORDER BY id DESC
|
|
1269
|
-
LIMIT 1
|
|
1270
|
-
`).get(localSessionId) as { source_turn_id: string | null } | undefined;
|
|
1271
|
-
return row?.source_turn_id ?? undefined;
|
|
1354
|
+
return this.getForkHistorySource(localSessionId)?.sourceTurnId;
|
|
1272
1355
|
}
|
|
1273
1356
|
|
|
1274
1357
|
private findCrossSessionParentTurnId(localSessionId: string): string | undefined {
|
|
@@ -2189,6 +2272,14 @@ function completedTurnTimestamp(record: CompletedTurnSnapshotRecord): number {
|
|
|
2189
2272
|
return Number.isFinite(timestamp) ? timestamp : 0;
|
|
2190
2273
|
}
|
|
2191
2274
|
|
|
2275
|
+
function stringValue(value: unknown): string | undefined {
|
|
2276
|
+
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
2277
|
+
}
|
|
2278
|
+
|
|
2279
|
+
function numberValue(value: unknown): number | undefined {
|
|
2280
|
+
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
2281
|
+
}
|
|
2282
|
+
|
|
2192
2283
|
function isIncompleteTurnAttemptStatus(status: TurnAttemptStatus): boolean {
|
|
2193
2284
|
return status === "accepted" || status === "running" || status === "recovering";
|
|
2194
2285
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { RestartNotificationTarget } from "./SafeRestartScheduler.js";
|
|
2
|
+
|
|
3
|
+
export function privateRestartNotificationTarget(userOpenId: string | undefined): RestartNotificationTarget {
|
|
4
|
+
const normalizedUserOpenId = userOpenId?.trim();
|
|
5
|
+
if (!normalizedUserOpenId) {
|
|
6
|
+
throw new Error(
|
|
7
|
+
"Cannot send CLI restart notifications to private chat because feishu.userOpenId is not configured. "
|
|
8
|
+
+ "Run agentbot init or pass --task <task>.",
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
return { contextKey: `open_id:${normalizedUserOpenId}` };
|
|
12
|
+
}
|
|
@@ -20,9 +20,11 @@ export function spawnStdioCommand(
|
|
|
20
20
|
command: string,
|
|
21
21
|
args: string[],
|
|
22
22
|
env: NodeJS.ProcessEnv,
|
|
23
|
+
cwd?: string,
|
|
23
24
|
): ChildProcessWithoutNullStreams {
|
|
24
25
|
const prepared = prepareCommand(command, args);
|
|
25
26
|
return spawn(prepared.command, prepared.args, {
|
|
27
|
+
cwd,
|
|
26
28
|
env,
|
|
27
29
|
stdio: ["pipe", "pipe", "pipe"],
|
|
28
30
|
windowsHide: true,
|