agim-cli 1.2.1 → 1.2.2
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 +52 -0
- package/dist/cli-ui/entry-menu.d.ts +2 -0
- package/dist/cli-ui/entry-menu.d.ts.map +1 -1
- package/dist/cli-ui/entry-menu.js +1 -0
- package/dist/cli-ui/entry-menu.js.map +1 -1
- package/dist/cli-ui/i18n.d.ts +5 -0
- package/dist/cli-ui/i18n.d.ts.map +1 -1
- package/dist/cli-ui/i18n.js +10 -0
- package/dist/cli-ui/i18n.js.map +1 -1
- package/dist/cli.js +75 -0
- package/dist/cli.js.map +1 -1
- package/dist/core/admin-bootstrap.d.ts +14 -0
- package/dist/core/admin-bootstrap.d.ts.map +1 -1
- package/dist/core/admin-bootstrap.js +21 -0
- package/dist/core/admin-bootstrap.js.map +1 -1
- package/dist/web/public/tasks.html +55 -1
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +54 -0
- package/dist/web/server.js.map +1 -1
- package/package.json +1 -1
|
@@ -91,6 +91,27 @@ export function ensureBootstrapTokenIfNeeded() {
|
|
|
91
91
|
console.log();
|
|
92
92
|
return token;
|
|
93
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* v1.2.2 — generate an admin INVITE token unconditionally (even when an
|
|
96
|
+
* admin already exists). Reuses the same bootstrap-token file + the same
|
|
97
|
+
* `/setup admin <token>` IM flow. Overwrites any existing unconsumed
|
|
98
|
+
* token so only the latest invite is valid at any time.
|
|
99
|
+
*
|
|
100
|
+
* Intended for an existing admin to onboard additional admins without
|
|
101
|
+
* SSH'ing into the server to look up the autogen bootstrap token.
|
|
102
|
+
* Triggered by `agim admin invite` CLI / the entry-menu option.
|
|
103
|
+
*/
|
|
104
|
+
export function generateAdminInviteToken() {
|
|
105
|
+
const token = generateToken();
|
|
106
|
+
mkdirSync(dirname(BOOTSTRAP_TOKEN_FILE), { recursive: true });
|
|
107
|
+
writeFileSync(BOOTSTRAP_TOKEN_FILE, token + '\n');
|
|
108
|
+
chmodSync(BOOTSTRAP_TOKEN_FILE, 0o600);
|
|
109
|
+
log.info({
|
|
110
|
+
event: 'admin-bootstrap.invite_generated',
|
|
111
|
+
file: BOOTSTRAP_TOKEN_FILE,
|
|
112
|
+
}, 'admin invite token generated (existing admin invoked invite flow)');
|
|
113
|
+
return { token, file: BOOTSTRAP_TOKEN_FILE };
|
|
114
|
+
}
|
|
94
115
|
/**
|
|
95
116
|
* Verify a candidate token + promote the caller to admin on success.
|
|
96
117
|
* Returns the outcome so the slash-command handler can craft the right
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"admin-bootstrap.js","sourceRoot":"","sources":["../../src/core/admin-bootstrap.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"admin-bootstrap.js","sourceRoot":"","sources":["../../src/core/admin-bootstrap.ts"],"names":[],"mappings":"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"}
|
|
@@ -259,6 +259,7 @@
|
|
|
259
259
|
memoryPersonaPlaceholder: '(No persona for this user yet — will be auto-generated at next consolidation, or write one manually.)',
|
|
260
260
|
memoryPersonaSave: 'Save persona',
|
|
261
261
|
memoryPersonaDelete: 'Delete persona',
|
|
262
|
+
memoryPersonaConsolidate: '🔁 Rebuild persona now',
|
|
262
263
|
memoryFactsCard: 'Facts',
|
|
263
264
|
memoryFactsSearch: 'Search (FTS5)',
|
|
264
265
|
memoryFactsCatAll: 'All types',
|
|
@@ -532,6 +533,7 @@
|
|
|
532
533
|
memoryPersonaPlaceholder: '(此用户暂无记忆画像 — 等下次 consolidation 自动生成,或手动写入)',
|
|
533
534
|
memoryPersonaSave: '保存记忆画像',
|
|
534
535
|
memoryPersonaDelete: '删除记忆画像',
|
|
536
|
+
memoryPersonaConsolidate: '🔁 立刻重建画像',
|
|
535
537
|
memoryFactsCard: 'Facts',
|
|
536
538
|
memoryFactsSearch: '搜索(FTS5)',
|
|
537
539
|
memoryFactsCatAll: '所有类型',
|
|
@@ -1244,9 +1246,10 @@
|
|
|
1244
1246
|
<span class="muted" id="mem-persona-meta" style="font-size:12px"></span>
|
|
1245
1247
|
</div>
|
|
1246
1248
|
<textarea id="mem-persona-text" rows="6" style="width:100%;font-family:ui-monospace,monospace;font-size:13px;box-sizing:border-box" data-i18n-attr="placeholder:memoryPersonaPlaceholder" placeholder="(此用户暂无记忆画像 — 等下次 consolidation 自动生成,或手动写入)"></textarea>
|
|
1247
|
-
<div class="actions" style="margin-top:8px;display:flex;gap:8px">
|
|
1249
|
+
<div class="actions" style="margin-top:8px;display:flex;gap:8px;flex-wrap:wrap">
|
|
1248
1250
|
<button type="button" id="btn-mem-persona-save" class="btn btn-primary" data-i18n="memoryPersonaSave">保存记忆画像</button>
|
|
1249
1251
|
<button type="button" id="btn-mem-persona-delete" class="btn" data-i18n="memoryPersonaDelete">删除记忆画像</button>
|
|
1252
|
+
<button type="button" id="btn-mem-persona-consolidate" class="btn" title="立刻跑一次 consolidation 重建画像,不等 24h 周期" data-i18n="memoryPersonaConsolidate">🔁 立刻重建画像</button>
|
|
1250
1253
|
</div>
|
|
1251
1254
|
<p class="muted" id="mem-persona-status" style="margin-top:6px;font-size:12px"></p>
|
|
1252
1255
|
</div>
|
|
@@ -3329,6 +3332,57 @@
|
|
|
3329
3332
|
if (status) status.textContent = '删除失败: ' + (err.message || err);
|
|
3330
3333
|
}
|
|
3331
3334
|
});
|
|
3335
|
+
document.getElementById('btn-mem-persona-consolidate')?.addEventListener('click', async () => {
|
|
3336
|
+
const status = document.getElementById('mem-persona-status');
|
|
3337
|
+
const btn = document.getElementById('btn-mem-persona-consolidate');
|
|
3338
|
+
if (btn) btn.disabled = true;
|
|
3339
|
+
if (status) status.textContent = '⏳ 已提交后台任务(每用户 1 次 LLM 调用,10–60 秒)…';
|
|
3340
|
+
let pollTimer = null;
|
|
3341
|
+
const stopPoll = () => { if (pollTimer) { clearInterval(pollTimer); pollTimer = null; } };
|
|
3342
|
+
try {
|
|
3343
|
+
// Async kickoff: server returns 202 + jobId immediately, then the
|
|
3344
|
+
// LLM call runs in the background. Polling avoids cloudflare /
|
|
3345
|
+
// nginx / browser fetch timeouts on long-held POSTs.
|
|
3346
|
+
const r = await api('/api/memory/consolidate', { method: 'POST' });
|
|
3347
|
+
const targetJobId = r.jobId;
|
|
3348
|
+
if (!targetJobId) throw new Error('server did not return jobId');
|
|
3349
|
+
const startedAt = Date.now();
|
|
3350
|
+
pollTimer = setInterval(async () => {
|
|
3351
|
+
try {
|
|
3352
|
+
const s = await api('/api/memory/consolidate/status');
|
|
3353
|
+
const job = (s.jobs || []).find(j => j.id === targetJobId);
|
|
3354
|
+
if (!job) return;
|
|
3355
|
+
const elapsed = ((Date.now() - startedAt) / 1000).toFixed(0);
|
|
3356
|
+
if (job.phase === 'running') {
|
|
3357
|
+
if (status) status.textContent = `⏳ 重建中 (${elapsed}s)…`;
|
|
3358
|
+
return;
|
|
3359
|
+
}
|
|
3360
|
+
stopPoll();
|
|
3361
|
+
if (btn) btn.disabled = false;
|
|
3362
|
+
if (job.phase === 'done') {
|
|
3363
|
+
const u = (job.result && job.result.updated) || 0;
|
|
3364
|
+
const n = (job.result && job.result.users) || 0;
|
|
3365
|
+
if (status) status.textContent = `✓ 完成 (${elapsed}s) · 处理 ${n} 个用户、更新 ${u} 个画像`;
|
|
3366
|
+
await loadMemoryUserDetail();
|
|
3367
|
+
} else {
|
|
3368
|
+
const e = (job.result && job.result.error) || 'unknown error';
|
|
3369
|
+
if (status) status.textContent = '失败: ' + e;
|
|
3370
|
+
}
|
|
3371
|
+
} catch (pollErr) {
|
|
3372
|
+
// Poll failures are non-fatal; UI keeps trying. Stop after 5 min.
|
|
3373
|
+
if (Date.now() - startedAt > 300_000) {
|
|
3374
|
+
stopPoll();
|
|
3375
|
+
if (btn) btn.disabled = false;
|
|
3376
|
+
if (status) status.textContent = '轮询超时(>5min),请刷新查看实际结果';
|
|
3377
|
+
}
|
|
3378
|
+
}
|
|
3379
|
+
}, 2000);
|
|
3380
|
+
} catch (err) {
|
|
3381
|
+
if (status) status.textContent = '失败: ' + (err.message || err);
|
|
3382
|
+
if (btn) btn.disabled = false;
|
|
3383
|
+
stopPoll();
|
|
3384
|
+
}
|
|
3385
|
+
});
|
|
3332
3386
|
document.getElementById('btn-mem-facts-clear-lowconf')?.addEventListener('click', async () => {
|
|
3333
3387
|
if (!memCurrentUser) return;
|
|
3334
3388
|
if (!confirm('删除 confidence ≤ 40% 的所有事实?')) return;
|
package/dist/web/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/web/server.ts"],"names":[],"mappings":"AA+JA,wBAAgB,iBAAiB,IAAI,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,CAOrE;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,MAAM,CAAA;CACrB,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/web/server.ts"],"names":[],"mappings":"AA+JA,wBAAgB,iBAAiB,IAAI,CAAC,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,CAOrE;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,MAAM,CAAA;CACrB,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAwxB/C"}
|
package/dist/web/server.js
CHANGED
|
@@ -615,6 +615,14 @@ export async function startWebServer(options) {
|
|
|
615
615
|
if (url.pathname === '/api/memory/vector/clear' && req.method === 'POST') {
|
|
616
616
|
return handleVectorClear(req, res, url);
|
|
617
617
|
}
|
|
618
|
+
// v1.2.2 — manual trigger for the daily consolidation. Useful when the
|
|
619
|
+
// user just wants a persona summary now without waiting 24h.
|
|
620
|
+
if (url.pathname === '/api/memory/consolidate' && req.method === 'POST') {
|
|
621
|
+
return handleMemoryConsolidate(req, res);
|
|
622
|
+
}
|
|
623
|
+
if (url.pathname === '/api/memory/consolidate/status' && req.method === 'GET') {
|
|
624
|
+
return handleMemoryConsolidateStatus(req, res);
|
|
625
|
+
}
|
|
618
626
|
// PR-B: HITL approvals — global pending list + per-reqId resolve.
|
|
619
627
|
if (url.pathname === '/api/approvals' && req.method === 'GET') {
|
|
620
628
|
return handleListApprovals(req, res);
|
|
@@ -2370,6 +2378,52 @@ async function handleVectorBackfill(req, res, url) {
|
|
|
2370
2378
|
sendJson(res, 500, { error: err instanceof Error ? err.message : String(err) });
|
|
2371
2379
|
}
|
|
2372
2380
|
}
|
|
2381
|
+
const consolidateJobs = new Map();
|
|
2382
|
+
function pickRecentConsolidate() {
|
|
2383
|
+
return Array.from(consolidateJobs.values())
|
|
2384
|
+
.sort((a, b) => b.startedAt - a.startedAt)
|
|
2385
|
+
.slice(0, 5);
|
|
2386
|
+
}
|
|
2387
|
+
async function handleMemoryConsolidate(_req, res) {
|
|
2388
|
+
try {
|
|
2389
|
+
// Dedupe: if a consolidate is already running, return that jobId.
|
|
2390
|
+
for (const j of consolidateJobs.values()) {
|
|
2391
|
+
if (j.phase === 'running') {
|
|
2392
|
+
sendJson(res, 202, { ok: true, jobId: j.id, alreadyRunning: true });
|
|
2393
|
+
return;
|
|
2394
|
+
}
|
|
2395
|
+
}
|
|
2396
|
+
const id = `consolidate-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
|
2397
|
+
const job = { id, startedAt: Date.now(), finishedAt: null, phase: 'running', result: {} };
|
|
2398
|
+
consolidateJobs.set(id, job);
|
|
2399
|
+
if (consolidateJobs.size > 50) {
|
|
2400
|
+
const oldest = Array.from(consolidateJobs.values()).sort((a, b) => a.startedAt - b.startedAt)[0];
|
|
2401
|
+
if (oldest)
|
|
2402
|
+
consolidateJobs.delete(oldest.id);
|
|
2403
|
+
}
|
|
2404
|
+
void (async () => {
|
|
2405
|
+
try {
|
|
2406
|
+
const { runConsolidationOnce } = await import('../core/memory-consolidate.js');
|
|
2407
|
+
const r = await runConsolidationOnce();
|
|
2408
|
+
job.finishedAt = Date.now();
|
|
2409
|
+
job.phase = 'done';
|
|
2410
|
+
job.result = r;
|
|
2411
|
+
}
|
|
2412
|
+
catch (err) {
|
|
2413
|
+
job.finishedAt = Date.now();
|
|
2414
|
+
job.phase = 'failed';
|
|
2415
|
+
job.result = { error: err instanceof Error ? err.message : String(err) };
|
|
2416
|
+
}
|
|
2417
|
+
})();
|
|
2418
|
+
sendJson(res, 202, { ok: true, jobId: id, hint: 'poll /api/memory/consolidate/status for progress' });
|
|
2419
|
+
}
|
|
2420
|
+
catch (err) {
|
|
2421
|
+
sendJson(res, 500, { error: err instanceof Error ? err.message : String(err) });
|
|
2422
|
+
}
|
|
2423
|
+
}
|
|
2424
|
+
async function handleMemoryConsolidateStatus(_req, res) {
|
|
2425
|
+
sendJson(res, 200, { jobs: pickRecentConsolidate() });
|
|
2426
|
+
}
|
|
2373
2427
|
async function handleVectorClear(_req, res, url) {
|
|
2374
2428
|
try {
|
|
2375
2429
|
const { clearEmbeddings } = await import('../core/memory.js');
|