@signetai/signet-memory-openclaw 0.77.4 → 0.77.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/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +634 -16
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -109,10 +109,13 @@ export declare function onPreCompaction(harness: string, options?: {
|
|
|
109
109
|
}): Promise<PreCompactionResult | null>;
|
|
110
110
|
export declare function onCompactionComplete(harness: string, summary: string, options?: {
|
|
111
111
|
daemonUrl?: string;
|
|
112
|
+
agentId?: string;
|
|
112
113
|
sessionKey?: string;
|
|
114
|
+
project?: string;
|
|
113
115
|
}): Promise<boolean>;
|
|
114
116
|
export declare function onSessionEnd(harness: string, options?: {
|
|
115
117
|
daemonUrl?: string;
|
|
118
|
+
agentId?: string;
|
|
116
119
|
transcriptPath?: string;
|
|
117
120
|
sessionKey?: string;
|
|
118
121
|
sessionId?: string;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,7 @@ var __export = (target, all) => {
|
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
// src/index.ts
|
|
17
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
17
18
|
import { homedir } from "node:os";
|
|
18
19
|
import { join as join3 } from "node:path";
|
|
19
20
|
|
|
@@ -8175,6 +8176,386 @@ function up43(db) {
|
|
|
8175
8176
|
ON memories(agent_id, visibility);
|
|
8176
8177
|
`);
|
|
8177
8178
|
}
|
|
8179
|
+
function addColumnIfMissing15(db, table, column, definition) {
|
|
8180
|
+
const cols = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
8181
|
+
if (cols.some((c) => c.name === column))
|
|
8182
|
+
return;
|
|
8183
|
+
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
|
8184
|
+
}
|
|
8185
|
+
function up44(db) {
|
|
8186
|
+
addColumnIfMissing15(db, "session_summaries", "source_type", "TEXT");
|
|
8187
|
+
addColumnIfMissing15(db, "session_summaries", "source_ref", "TEXT");
|
|
8188
|
+
addColumnIfMissing15(db, "session_summaries", "meta_json", "TEXT");
|
|
8189
|
+
db.exec(`
|
|
8190
|
+
UPDATE session_summaries
|
|
8191
|
+
SET source_type = CASE
|
|
8192
|
+
WHEN source_type IS NOT NULL THEN source_type
|
|
8193
|
+
WHEN kind = 'session' THEN 'summary'
|
|
8194
|
+
WHEN kind IN ('arc', 'epoch') THEN 'condensation'
|
|
8195
|
+
ELSE kind
|
|
8196
|
+
END
|
|
8197
|
+
WHERE source_type IS NULL;
|
|
8198
|
+
|
|
8199
|
+
CREATE INDEX IF NOT EXISTS idx_summaries_source_type
|
|
8200
|
+
ON session_summaries(source_type);
|
|
8201
|
+
CREATE INDEX IF NOT EXISTS idx_summaries_source_ref
|
|
8202
|
+
ON session_summaries(source_ref);
|
|
8203
|
+
`);
|
|
8204
|
+
}
|
|
8205
|
+
function addColumnIfMissing16(db, table, column, definition) {
|
|
8206
|
+
const cols = db.prepare(`PRAGMA table_info(${table})`).all();
|
|
8207
|
+
if (cols.some((col) => col.name === column))
|
|
8208
|
+
return;
|
|
8209
|
+
db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${definition}`);
|
|
8210
|
+
}
|
|
8211
|
+
function up45(db) {
|
|
8212
|
+
addColumnIfMissing16(db, "session_transcripts", "updated_at", "TEXT");
|
|
8213
|
+
addColumnIfMissing16(db, "summary_jobs", "agent_id", "TEXT NOT NULL DEFAULT 'default'");
|
|
8214
|
+
addColumnIfMissing16(db, "session_scores", "agent_id", "TEXT NOT NULL DEFAULT 'default'");
|
|
8215
|
+
db.exec(`
|
|
8216
|
+
UPDATE session_transcripts
|
|
8217
|
+
SET updated_at = COALESCE(updated_at, created_at)
|
|
8218
|
+
WHERE updated_at IS NULL;
|
|
8219
|
+
|
|
8220
|
+
UPDATE summary_jobs
|
|
8221
|
+
SET agent_id = COALESCE(agent_id, 'default')
|
|
8222
|
+
WHERE agent_id IS NULL;
|
|
8223
|
+
|
|
8224
|
+
UPDATE session_scores
|
|
8225
|
+
SET agent_id = COALESCE(agent_id, 'default')
|
|
8226
|
+
WHERE agent_id IS NULL;
|
|
8227
|
+
|
|
8228
|
+
CREATE INDEX IF NOT EXISTS idx_st_agent_updated
|
|
8229
|
+
ON session_transcripts(agent_id, updated_at);
|
|
8230
|
+
CREATE INDEX IF NOT EXISTS idx_summary_jobs_agent
|
|
8231
|
+
ON summary_jobs(agent_id, created_at);
|
|
8232
|
+
CREATE INDEX IF NOT EXISTS idx_session_scores_agent_session
|
|
8233
|
+
ON session_scores(agent_id, session_key, created_at);
|
|
8234
|
+
`);
|
|
8235
|
+
db.exec(`
|
|
8236
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS session_transcripts_fts USING fts5(
|
|
8237
|
+
content,
|
|
8238
|
+
content='session_transcripts',
|
|
8239
|
+
content_rowid='rowid'
|
|
8240
|
+
)
|
|
8241
|
+
`);
|
|
8242
|
+
db.exec(`
|
|
8243
|
+
CREATE TRIGGER IF NOT EXISTS session_transcripts_fts_ai AFTER INSERT ON session_transcripts BEGIN
|
|
8244
|
+
INSERT INTO session_transcripts_fts(rowid, content)
|
|
8245
|
+
VALUES (new.rowid, new.content);
|
|
8246
|
+
END
|
|
8247
|
+
`);
|
|
8248
|
+
db.exec(`
|
|
8249
|
+
CREATE TRIGGER IF NOT EXISTS session_transcripts_fts_ad AFTER DELETE ON session_transcripts BEGIN
|
|
8250
|
+
INSERT INTO session_transcripts_fts(session_transcripts_fts, rowid, content)
|
|
8251
|
+
VALUES ('delete', old.rowid, old.content);
|
|
8252
|
+
END
|
|
8253
|
+
`);
|
|
8254
|
+
db.exec(`
|
|
8255
|
+
CREATE TRIGGER IF NOT EXISTS session_transcripts_fts_au AFTER UPDATE ON session_transcripts BEGIN
|
|
8256
|
+
INSERT INTO session_transcripts_fts(session_transcripts_fts, rowid, content)
|
|
8257
|
+
VALUES ('delete', old.rowid, old.content);
|
|
8258
|
+
INSERT INTO session_transcripts_fts(rowid, content)
|
|
8259
|
+
VALUES (new.rowid, new.content);
|
|
8260
|
+
END
|
|
8261
|
+
`);
|
|
8262
|
+
db.exec(`
|
|
8263
|
+
INSERT INTO session_transcripts_fts(session_transcripts_fts)
|
|
8264
|
+
VALUES ('rebuild');
|
|
8265
|
+
`);
|
|
8266
|
+
db.exec(`
|
|
8267
|
+
CREATE TABLE IF NOT EXISTS memory_md_heads (
|
|
8268
|
+
agent_id TEXT PRIMARY KEY,
|
|
8269
|
+
content TEXT NOT NULL DEFAULT '',
|
|
8270
|
+
content_hash TEXT NOT NULL DEFAULT '',
|
|
8271
|
+
revision INTEGER NOT NULL DEFAULT 0,
|
|
8272
|
+
updated_at TEXT NOT NULL,
|
|
8273
|
+
lease_token TEXT,
|
|
8274
|
+
lease_owner TEXT,
|
|
8275
|
+
lease_expires_at TEXT
|
|
8276
|
+
);
|
|
8277
|
+
|
|
8278
|
+
CREATE INDEX IF NOT EXISTS idx_memory_md_heads_lease
|
|
8279
|
+
ON memory_md_heads(lease_expires_at);
|
|
8280
|
+
`);
|
|
8281
|
+
}
|
|
8282
|
+
function up46(db) {
|
|
8283
|
+
db.exec(`
|
|
8284
|
+
DROP INDEX IF EXISTS idx_summaries_session_depth;
|
|
8285
|
+
|
|
8286
|
+
CREATE TEMP TABLE IF NOT EXISTS session_summary_duplicate_map AS
|
|
8287
|
+
WITH ranked AS (
|
|
8288
|
+
SELECT
|
|
8289
|
+
id,
|
|
8290
|
+
agent_id,
|
|
8291
|
+
session_key,
|
|
8292
|
+
depth,
|
|
8293
|
+
ROW_NUMBER() OVER (
|
|
8294
|
+
PARTITION BY agent_id, session_key, depth
|
|
8295
|
+
ORDER BY latest_at DESC, created_at DESC, id ASC
|
|
8296
|
+
) AS rn
|
|
8297
|
+
FROM session_summaries
|
|
8298
|
+
WHERE session_key IS NOT NULL
|
|
8299
|
+
AND COALESCE(source_type, 'summary') = 'summary'
|
|
8300
|
+
)
|
|
8301
|
+
SELECT dup.id AS drop_id, keep.id AS keep_id
|
|
8302
|
+
FROM ranked dup
|
|
8303
|
+
JOIN ranked keep
|
|
8304
|
+
ON keep.agent_id = dup.agent_id
|
|
8305
|
+
AND keep.session_key = dup.session_key
|
|
8306
|
+
AND keep.depth = dup.depth
|
|
8307
|
+
AND keep.rn = 1
|
|
8308
|
+
WHERE dup.rn > 1;
|
|
8309
|
+
|
|
8310
|
+
INSERT OR IGNORE INTO session_summary_memories (summary_id, memory_id)
|
|
8311
|
+
SELECT map.keep_id, link.memory_id
|
|
8312
|
+
FROM session_summary_duplicate_map map
|
|
8313
|
+
JOIN session_summary_memories link ON link.summary_id = map.drop_id;
|
|
8314
|
+
|
|
8315
|
+
INSERT OR IGNORE INTO session_summary_children (parent_id, child_id, ordinal)
|
|
8316
|
+
SELECT
|
|
8317
|
+
COALESCE(parent_map.keep_id, rel.parent_id),
|
|
8318
|
+
COALESCE(child_map.keep_id, rel.child_id),
|
|
8319
|
+
rel.ordinal
|
|
8320
|
+
FROM session_summary_children rel
|
|
8321
|
+
LEFT JOIN session_summary_duplicate_map parent_map ON parent_map.drop_id = rel.parent_id
|
|
8322
|
+
LEFT JOIN session_summary_duplicate_map child_map ON child_map.drop_id = rel.child_id
|
|
8323
|
+
WHERE parent_map.drop_id IS NOT NULL OR child_map.drop_id IS NOT NULL;
|
|
8324
|
+
|
|
8325
|
+
DELETE FROM session_summary_children
|
|
8326
|
+
WHERE parent_id IN (SELECT drop_id FROM session_summary_duplicate_map)
|
|
8327
|
+
OR child_id IN (SELECT drop_id FROM session_summary_duplicate_map);
|
|
8328
|
+
|
|
8329
|
+
DELETE FROM session_summary_memories
|
|
8330
|
+
WHERE summary_id IN (SELECT drop_id FROM session_summary_duplicate_map);
|
|
8331
|
+
|
|
8332
|
+
DELETE FROM session_summaries
|
|
8333
|
+
WHERE id IN (SELECT drop_id FROM session_summary_duplicate_map);
|
|
8334
|
+
|
|
8335
|
+
DROP TABLE session_summary_duplicate_map;
|
|
8336
|
+
|
|
8337
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_summaries_session_depth_summary
|
|
8338
|
+
ON session_summaries(agent_id, session_key, depth)
|
|
8339
|
+
WHERE session_key IS NOT NULL
|
|
8340
|
+
AND COALESCE(source_type, 'summary') = 'summary';
|
|
8341
|
+
`);
|
|
8342
|
+
}
|
|
8343
|
+
function up47(db) {
|
|
8344
|
+
db.exec(`
|
|
8345
|
+
DROP TRIGGER IF EXISTS session_transcripts_fts_ai;
|
|
8346
|
+
DROP TRIGGER IF EXISTS session_transcripts_fts_ad;
|
|
8347
|
+
DROP TRIGGER IF EXISTS session_transcripts_fts_au;
|
|
8348
|
+
DROP TABLE IF EXISTS session_transcripts_fts;
|
|
8349
|
+
|
|
8350
|
+
CREATE TABLE IF NOT EXISTS session_transcripts_next (
|
|
8351
|
+
session_key TEXT NOT NULL,
|
|
8352
|
+
content TEXT NOT NULL,
|
|
8353
|
+
harness TEXT,
|
|
8354
|
+
project TEXT,
|
|
8355
|
+
agent_id TEXT NOT NULL DEFAULT 'default',
|
|
8356
|
+
created_at TEXT NOT NULL,
|
|
8357
|
+
updated_at TEXT,
|
|
8358
|
+
PRIMARY KEY (agent_id, session_key)
|
|
8359
|
+
);
|
|
8360
|
+
|
|
8361
|
+
INSERT INTO session_transcripts_next (
|
|
8362
|
+
session_key,
|
|
8363
|
+
content,
|
|
8364
|
+
harness,
|
|
8365
|
+
project,
|
|
8366
|
+
agent_id,
|
|
8367
|
+
created_at,
|
|
8368
|
+
updated_at
|
|
8369
|
+
)
|
|
8370
|
+
SELECT
|
|
8371
|
+
session_key,
|
|
8372
|
+
content,
|
|
8373
|
+
harness,
|
|
8374
|
+
project,
|
|
8375
|
+
agent_id,
|
|
8376
|
+
created_at,
|
|
8377
|
+
updated_at
|
|
8378
|
+
FROM (
|
|
8379
|
+
SELECT
|
|
8380
|
+
session_key,
|
|
8381
|
+
content,
|
|
8382
|
+
harness,
|
|
8383
|
+
project,
|
|
8384
|
+
COALESCE(agent_id, 'default') AS agent_id,
|
|
8385
|
+
created_at,
|
|
8386
|
+
COALESCE(updated_at, created_at) AS updated_at,
|
|
8387
|
+
ROW_NUMBER() OVER (
|
|
8388
|
+
PARTITION BY COALESCE(agent_id, 'default'), session_key
|
|
8389
|
+
ORDER BY COALESCE(updated_at, created_at) DESC, LENGTH(content) DESC, created_at DESC, rowid DESC
|
|
8390
|
+
) AS rn
|
|
8391
|
+
FROM session_transcripts
|
|
8392
|
+
) ranked
|
|
8393
|
+
WHERE rn = 1;
|
|
8394
|
+
|
|
8395
|
+
DROP TABLE session_transcripts;
|
|
8396
|
+
ALTER TABLE session_transcripts_next RENAME TO session_transcripts;
|
|
8397
|
+
|
|
8398
|
+
CREATE INDEX IF NOT EXISTS idx_st_project
|
|
8399
|
+
ON session_transcripts(project);
|
|
8400
|
+
CREATE INDEX IF NOT EXISTS idx_st_created
|
|
8401
|
+
ON session_transcripts(created_at);
|
|
8402
|
+
CREATE INDEX IF NOT EXISTS idx_st_agent_updated
|
|
8403
|
+
ON session_transcripts(agent_id, updated_at);
|
|
8404
|
+
|
|
8405
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS session_transcripts_fts USING fts5(
|
|
8406
|
+
content,
|
|
8407
|
+
content='session_transcripts',
|
|
8408
|
+
content_rowid='rowid'
|
|
8409
|
+
);
|
|
8410
|
+
|
|
8411
|
+
CREATE TRIGGER IF NOT EXISTS session_transcripts_fts_ai AFTER INSERT ON session_transcripts BEGIN
|
|
8412
|
+
INSERT INTO session_transcripts_fts(rowid, content)
|
|
8413
|
+
VALUES (new.rowid, new.content);
|
|
8414
|
+
END;
|
|
8415
|
+
|
|
8416
|
+
CREATE TRIGGER IF NOT EXISTS session_transcripts_fts_ad AFTER DELETE ON session_transcripts BEGIN
|
|
8417
|
+
INSERT INTO session_transcripts_fts(session_transcripts_fts, rowid, content)
|
|
8418
|
+
VALUES ('delete', old.rowid, old.content);
|
|
8419
|
+
END;
|
|
8420
|
+
|
|
8421
|
+
CREATE TRIGGER IF NOT EXISTS session_transcripts_fts_au AFTER UPDATE ON session_transcripts BEGIN
|
|
8422
|
+
INSERT INTO session_transcripts_fts(session_transcripts_fts, rowid, content)
|
|
8423
|
+
VALUES ('delete', old.rowid, old.content);
|
|
8424
|
+
INSERT INTO session_transcripts_fts(rowid, content)
|
|
8425
|
+
VALUES (new.rowid, new.content);
|
|
8426
|
+
END;
|
|
8427
|
+
|
|
8428
|
+
INSERT INTO session_transcripts_fts(session_transcripts_fts)
|
|
8429
|
+
VALUES ('rebuild');
|
|
8430
|
+
|
|
8431
|
+
DROP INDEX IF EXISTS idx_summaries_session_depth;
|
|
8432
|
+
DROP INDEX IF EXISTS idx_summaries_session_depth_summary;
|
|
8433
|
+
CREATE INDEX IF NOT EXISTS idx_summaries_agent_session_key
|
|
8434
|
+
ON session_summaries(agent_id, session_key);
|
|
8435
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_summaries_agent_session_depth_summary
|
|
8436
|
+
ON session_summaries(agent_id, session_key, depth)
|
|
8437
|
+
WHERE session_key IS NOT NULL
|
|
8438
|
+
AND COALESCE(source_type, 'summary') = 'summary';
|
|
8439
|
+
`);
|
|
8440
|
+
}
|
|
8441
|
+
function up48(db) {
|
|
8442
|
+
db.exec(`
|
|
8443
|
+
CREATE TABLE IF NOT EXISTS memory_thread_heads (
|
|
8444
|
+
agent_id TEXT NOT NULL DEFAULT 'default',
|
|
8445
|
+
thread_key TEXT NOT NULL,
|
|
8446
|
+
label TEXT NOT NULL,
|
|
8447
|
+
project TEXT,
|
|
8448
|
+
session_key TEXT,
|
|
8449
|
+
source_type TEXT NOT NULL DEFAULT 'summary',
|
|
8450
|
+
source_ref TEXT,
|
|
8451
|
+
harness TEXT,
|
|
8452
|
+
node_id TEXT NOT NULL,
|
|
8453
|
+
latest_at TEXT NOT NULL,
|
|
8454
|
+
sample TEXT NOT NULL,
|
|
8455
|
+
updated_at TEXT NOT NULL,
|
|
8456
|
+
PRIMARY KEY (agent_id, thread_key)
|
|
8457
|
+
);
|
|
8458
|
+
|
|
8459
|
+
CREATE INDEX IF NOT EXISTS idx_thread_heads_agent_latest
|
|
8460
|
+
ON memory_thread_heads(agent_id, latest_at DESC);
|
|
8461
|
+
CREATE INDEX IF NOT EXISTS idx_thread_heads_agent_project
|
|
8462
|
+
ON memory_thread_heads(agent_id, project);
|
|
8463
|
+
|
|
8464
|
+
INSERT INTO memory_thread_heads (
|
|
8465
|
+
agent_id, thread_key, label, project, session_key, source_type,
|
|
8466
|
+
source_ref, harness, node_id, latest_at, sample, updated_at
|
|
8467
|
+
)
|
|
8468
|
+
SELECT
|
|
8469
|
+
ss.agent_id,
|
|
8470
|
+
CASE
|
|
8471
|
+
WHEN ss.harness IS NOT NULL AND TRIM(ss.harness) != ''
|
|
8472
|
+
AND (ss.project IS NULL OR TRIM(ss.project) = '')
|
|
8473
|
+
AND (ss.source_ref IS NULL OR TRIM(ss.source_ref) = '')
|
|
8474
|
+
AND (ss.session_key IS NULL OR TRIM(ss.session_key) = '')
|
|
8475
|
+
THEN 'harness:' || TRIM(ss.harness)
|
|
8476
|
+
ELSE
|
|
8477
|
+
CASE
|
|
8478
|
+
WHEN ss.source_ref IS NOT NULL AND TRIM(ss.source_ref) != '' AND ss.project IS NOT NULL AND TRIM(ss.project) != '' THEN
|
|
8479
|
+
'project:' || TRIM(ss.project) || '|source:' || TRIM(ss.source_ref)
|
|
8480
|
+
WHEN ss.source_ref IS NOT NULL AND TRIM(ss.source_ref) != '' THEN 'source:' || TRIM(ss.source_ref)
|
|
8481
|
+
WHEN ss.session_key IS NOT NULL AND TRIM(ss.session_key) != '' AND ss.project IS NOT NULL AND TRIM(ss.project) != '' THEN
|
|
8482
|
+
'project:' || TRIM(ss.project) || '|session:' || TRIM(ss.session_key)
|
|
8483
|
+
WHEN ss.project IS NOT NULL AND TRIM(ss.project) != '' THEN 'project:' || TRIM(ss.project)
|
|
8484
|
+
WHEN ss.session_key IS NOT NULL AND TRIM(ss.session_key) != '' THEN 'session:' || TRIM(ss.session_key)
|
|
8485
|
+
ELSE 'thread:unscoped'
|
|
8486
|
+
END ||
|
|
8487
|
+
CASE
|
|
8488
|
+
WHEN ss.harness IS NOT NULL AND TRIM(ss.harness) != '' THEN '|harness:' || TRIM(ss.harness)
|
|
8489
|
+
ELSE ''
|
|
8490
|
+
END
|
|
8491
|
+
END AS thread_key,
|
|
8492
|
+
CASE
|
|
8493
|
+
WHEN ss.source_ref IS NOT NULL AND TRIM(ss.source_ref) != '' AND ss.project IS NOT NULL AND TRIM(ss.project) != '' THEN
|
|
8494
|
+
'project:' || TRIM(ss.project) || '#source:' || TRIM(ss.source_ref)
|
|
8495
|
+
WHEN ss.source_ref IS NOT NULL AND TRIM(ss.source_ref) != '' THEN 'source:' || TRIM(ss.source_ref)
|
|
8496
|
+
WHEN ss.session_key IS NOT NULL AND TRIM(ss.session_key) != '' AND ss.project IS NOT NULL AND TRIM(ss.project) != '' THEN
|
|
8497
|
+
'project:' || TRIM(ss.project) || '#session:' || TRIM(ss.session_key)
|
|
8498
|
+
WHEN ss.project IS NOT NULL AND TRIM(ss.project) != '' THEN 'project:' || TRIM(ss.project)
|
|
8499
|
+
WHEN ss.session_key IS NOT NULL AND TRIM(ss.session_key) != '' THEN 'session:' || TRIM(ss.session_key)
|
|
8500
|
+
WHEN ss.harness IS NOT NULL AND TRIM(ss.harness) != '' THEN 'harness:' || TRIM(ss.harness)
|
|
8501
|
+
ELSE 'thread:unscoped'
|
|
8502
|
+
END AS label,
|
|
8503
|
+
ss.project,
|
|
8504
|
+
ss.session_key,
|
|
8505
|
+
COALESCE(ss.source_type, ss.kind, 'summary') AS source_type,
|
|
8506
|
+
ss.source_ref,
|
|
8507
|
+
ss.harness,
|
|
8508
|
+
ss.id AS node_id,
|
|
8509
|
+
ss.latest_at,
|
|
8510
|
+
SUBSTR(REPLACE(REPLACE(TRIM(ss.content), CHAR(10), ' '), CHAR(13), ' '), 1, 240) AS sample,
|
|
8511
|
+
ss.latest_at AS updated_at
|
|
8512
|
+
FROM (
|
|
8513
|
+
SELECT
|
|
8514
|
+
s0.*,
|
|
8515
|
+
ROW_NUMBER() OVER (
|
|
8516
|
+
PARTITION BY s0.agent_id,
|
|
8517
|
+
CASE
|
|
8518
|
+
WHEN s0.harness IS NOT NULL AND TRIM(s0.harness) != ''
|
|
8519
|
+
AND (s0.project IS NULL OR TRIM(s0.project) = '')
|
|
8520
|
+
AND (s0.source_ref IS NULL OR TRIM(s0.source_ref) = '')
|
|
8521
|
+
AND (s0.session_key IS NULL OR TRIM(s0.session_key) = '')
|
|
8522
|
+
THEN 'harness:' || TRIM(s0.harness)
|
|
8523
|
+
ELSE
|
|
8524
|
+
CASE
|
|
8525
|
+
WHEN s0.source_ref IS NOT NULL AND TRIM(s0.source_ref) != '' AND s0.project IS NOT NULL AND TRIM(s0.project) != '' THEN
|
|
8526
|
+
'project:' || TRIM(s0.project) || '|source:' || TRIM(s0.source_ref)
|
|
8527
|
+
WHEN s0.source_ref IS NOT NULL AND TRIM(s0.source_ref) != '' THEN 'source:' || TRIM(s0.source_ref)
|
|
8528
|
+
WHEN s0.session_key IS NOT NULL AND TRIM(s0.session_key) != '' AND s0.project IS NOT NULL AND TRIM(s0.project) != '' THEN
|
|
8529
|
+
'project:' || TRIM(s0.project) || '|session:' || TRIM(s0.session_key)
|
|
8530
|
+
WHEN s0.project IS NOT NULL AND TRIM(s0.project) != '' THEN 'project:' || TRIM(s0.project)
|
|
8531
|
+
WHEN s0.session_key IS NOT NULL AND TRIM(s0.session_key) != '' THEN 'session:' || TRIM(s0.session_key)
|
|
8532
|
+
ELSE 'thread:unscoped'
|
|
8533
|
+
END ||
|
|
8534
|
+
CASE
|
|
8535
|
+
WHEN s0.harness IS NOT NULL AND TRIM(s0.harness) != '' THEN '|harness:' || TRIM(s0.harness)
|
|
8536
|
+
ELSE ''
|
|
8537
|
+
END
|
|
8538
|
+
END
|
|
8539
|
+
ORDER BY s0.latest_at DESC, s0.created_at DESC
|
|
8540
|
+
) AS rn
|
|
8541
|
+
FROM session_summaries s0
|
|
8542
|
+
WHERE COALESCE(s0.source_type, s0.kind) != 'chunk'
|
|
8543
|
+
) ss
|
|
8544
|
+
WHERE ss.rn = 1
|
|
8545
|
+
ON CONFLICT(agent_id, thread_key) DO UPDATE SET
|
|
8546
|
+
label = excluded.label,
|
|
8547
|
+
project = excluded.project,
|
|
8548
|
+
session_key = excluded.session_key,
|
|
8549
|
+
source_type = excluded.source_type,
|
|
8550
|
+
source_ref = excluded.source_ref,
|
|
8551
|
+
harness = excluded.harness,
|
|
8552
|
+
node_id = excluded.node_id,
|
|
8553
|
+
latest_at = excluded.latest_at,
|
|
8554
|
+
sample = excluded.sample,
|
|
8555
|
+
updated_at = excluded.updated_at
|
|
8556
|
+
WHERE excluded.latest_at >= memory_thread_heads.latest_at;
|
|
8557
|
+
`);
|
|
8558
|
+
}
|
|
8178
8559
|
var MIGRATIONS = [
|
|
8179
8560
|
{
|
|
8180
8561
|
version: 1,
|
|
@@ -8508,6 +8889,49 @@ var MIGRATIONS = [
|
|
|
8508
8889
|
{ table: "memories", column: "visibility" }
|
|
8509
8890
|
]
|
|
8510
8891
|
}
|
|
8892
|
+
},
|
|
8893
|
+
{
|
|
8894
|
+
version: 44,
|
|
8895
|
+
name: "memory-md-temporal-head",
|
|
8896
|
+
up: up44,
|
|
8897
|
+
artifacts: {
|
|
8898
|
+
columns: [
|
|
8899
|
+
{ table: "session_summaries", column: "source_type" },
|
|
8900
|
+
{ table: "session_summaries", column: "source_ref" },
|
|
8901
|
+
{ table: "session_summaries", column: "meta_json" }
|
|
8902
|
+
]
|
|
8903
|
+
}
|
|
8904
|
+
},
|
|
8905
|
+
{
|
|
8906
|
+
version: 45,
|
|
8907
|
+
name: "lossless-working-memory-hardening",
|
|
8908
|
+
up: up45,
|
|
8909
|
+
artifacts: {
|
|
8910
|
+
tables: ["session_transcripts_fts", "memory_md_heads"],
|
|
8911
|
+
columns: [
|
|
8912
|
+
{ table: "session_transcripts", column: "updated_at" },
|
|
8913
|
+
{ table: "summary_jobs", column: "agent_id" },
|
|
8914
|
+
{ table: "session_scores", column: "agent_id" }
|
|
8915
|
+
]
|
|
8916
|
+
}
|
|
8917
|
+
},
|
|
8918
|
+
{
|
|
8919
|
+
version: 46,
|
|
8920
|
+
name: "session-summary-uniqueness",
|
|
8921
|
+
up: up46
|
|
8922
|
+
},
|
|
8923
|
+
{
|
|
8924
|
+
version: 47,
|
|
8925
|
+
name: "agent-scoped-temporal-uniqueness",
|
|
8926
|
+
up: up47
|
|
8927
|
+
},
|
|
8928
|
+
{
|
|
8929
|
+
version: 48,
|
|
8930
|
+
name: "thread-heads",
|
|
8931
|
+
up: up48,
|
|
8932
|
+
artifacts: {
|
|
8933
|
+
tables: ["memory_thread_heads"]
|
|
8934
|
+
}
|
|
8511
8935
|
}
|
|
8512
8936
|
];
|
|
8513
8937
|
var LATEST_SCHEMA_VERSION = MIGRATIONS[MIGRATIONS.length - 1]?.version ?? 0;
|
|
@@ -11351,6 +11775,7 @@ var DEFAULT_DAEMON_URL = "http://localhost:3850";
|
|
|
11351
11775
|
var RUNTIME_PATH = "plugin";
|
|
11352
11776
|
var READ_TIMEOUT = 5000;
|
|
11353
11777
|
var WRITE_TIMEOUT = 1e4;
|
|
11778
|
+
var COMPACTION_HOOK_DEDUPE_MS = 1000;
|
|
11354
11779
|
var METADATA_LINE_PREFIXES = [
|
|
11355
11780
|
"<<<EXTERNAL_UNTRUSTED_CONTENT",
|
|
11356
11781
|
">>>",
|
|
@@ -11589,7 +12014,9 @@ async function onCompactionComplete(harness, summary, options = {}) {
|
|
|
11589
12014
|
body: {
|
|
11590
12015
|
harness,
|
|
11591
12016
|
summary,
|
|
12017
|
+
agentId: options.agentId,
|
|
11592
12018
|
sessionKey: options.sessionKey,
|
|
12019
|
+
project: options.project,
|
|
11593
12020
|
runtimePath: RUNTIME_PATH
|
|
11594
12021
|
},
|
|
11595
12022
|
timeout: WRITE_TIMEOUT
|
|
@@ -11601,6 +12028,7 @@ async function onSessionEnd(harness, options = {}) {
|
|
|
11601
12028
|
method: "POST",
|
|
11602
12029
|
body: {
|
|
11603
12030
|
harness,
|
|
12031
|
+
agentId: options.agentId,
|
|
11604
12032
|
transcriptPath: options.transcriptPath,
|
|
11605
12033
|
sessionKey: options.sessionKey,
|
|
11606
12034
|
sessionId: options.sessionId,
|
|
@@ -11752,9 +12180,9 @@ function textResult(text, details) {
|
|
|
11752
12180
|
};
|
|
11753
12181
|
}
|
|
11754
12182
|
var SESSIONLESS_DEDUPE_MS = 1000;
|
|
11755
|
-
function cleanupTimedMap(map, now) {
|
|
12183
|
+
function cleanupTimedMap(map, now, ttlMs = SESSIONLESS_DEDUPE_MS) {
|
|
11756
12184
|
for (const [key, ts] of map) {
|
|
11757
|
-
if (now - ts >
|
|
12185
|
+
if (now - ts > ttlMs) {
|
|
11758
12186
|
map.delete(key);
|
|
11759
12187
|
}
|
|
11760
12188
|
}
|
|
@@ -11777,6 +12205,77 @@ function buildSessionlessTurnKey(event, agentId) {
|
|
|
11777
12205
|
const messageCount = Array.isArray(event.messages) ? event.messages.length : -1;
|
|
11778
12206
|
return `${agentId ?? "-"}|${messageCount}|${normalizedPrompt}`;
|
|
11779
12207
|
}
|
|
12208
|
+
function buildScopedSessionKey(sessionKey, agentId) {
|
|
12209
|
+
if (!sessionKey)
|
|
12210
|
+
return;
|
|
12211
|
+
return `${agentId ?? "-"}|${sessionKey}`;
|
|
12212
|
+
}
|
|
12213
|
+
function readString(value) {
|
|
12214
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
|
|
12215
|
+
}
|
|
12216
|
+
function readNumber(value) {
|
|
12217
|
+
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
12218
|
+
}
|
|
12219
|
+
function resolveCompactionSessionFile(event, sessionFile) {
|
|
12220
|
+
const compaction = isRecord(event.compaction) ? event.compaction : undefined;
|
|
12221
|
+
return firstNonEmptyString(event.sessionFile, event.session_file, compaction?.sessionFile, compaction?.session_file, sessionFile);
|
|
12222
|
+
}
|
|
12223
|
+
function readSessionFileProject(sessionFile) {
|
|
12224
|
+
if (!sessionFile || !existsSync(sessionFile))
|
|
12225
|
+
return;
|
|
12226
|
+
try {
|
|
12227
|
+
const lines = readFileSync(sessionFile, "utf-8").split(`
|
|
12228
|
+
`).map((line) => line.trim()).filter((line) => line.length > 0);
|
|
12229
|
+
for (const line of lines) {
|
|
12230
|
+
try {
|
|
12231
|
+
const row = JSON.parse(line);
|
|
12232
|
+
if (!isRecord(row) || row.type !== "session")
|
|
12233
|
+
continue;
|
|
12234
|
+
return firstNonEmptyString(row.cwd, row.project, row.workspace);
|
|
12235
|
+
} catch {}
|
|
12236
|
+
}
|
|
12237
|
+
} catch {}
|
|
12238
|
+
return;
|
|
12239
|
+
}
|
|
12240
|
+
function extractCompactionSummary(event, sessionFile) {
|
|
12241
|
+
const direct = readString(event.summary);
|
|
12242
|
+
if (direct)
|
|
12243
|
+
return direct;
|
|
12244
|
+
const compaction = isRecord(event.compaction) ? event.compaction : undefined;
|
|
12245
|
+
const nested = readString(compaction?.summary);
|
|
12246
|
+
if (nested)
|
|
12247
|
+
return nested;
|
|
12248
|
+
if (!sessionFile || !existsSync(sessionFile))
|
|
12249
|
+
return;
|
|
12250
|
+
try {
|
|
12251
|
+
const lines = readFileSync(sessionFile, "utf-8").split(`
|
|
12252
|
+
`).map((line) => line.trim()).filter((line) => line.length > 0);
|
|
12253
|
+
for (let i = lines.length - 1;i >= 0; i--) {
|
|
12254
|
+
try {
|
|
12255
|
+
const row = JSON.parse(lines[i]);
|
|
12256
|
+
if (!isRecord(row) || row.type !== "compaction")
|
|
12257
|
+
continue;
|
|
12258
|
+
const summary = readString(row.summary);
|
|
12259
|
+
if (summary)
|
|
12260
|
+
return summary;
|
|
12261
|
+
} catch {}
|
|
12262
|
+
}
|
|
12263
|
+
} catch {}
|
|
12264
|
+
return;
|
|
12265
|
+
}
|
|
12266
|
+
function buildCompactionEventKey(event, options) {
|
|
12267
|
+
const compaction = isRecord(event.compaction) ? event.compaction : undefined;
|
|
12268
|
+
const parts = [
|
|
12269
|
+
options.agentId ?? "-",
|
|
12270
|
+
options.sessionKey ?? "-",
|
|
12271
|
+
readString(event.runId) ?? readString(compaction?.runId) ?? "-",
|
|
12272
|
+
readString(event.id) ?? readString(compaction?.id) ?? "-",
|
|
12273
|
+
String(readNumber(event.messageCount) ?? readNumber(event.compactingCount) ?? readNumber(event.compactedCount) ?? readNumber(compaction?.messageCount) ?? readNumber(compaction?.compactingCount) ?? readNumber(compaction?.compactedCount) ?? -1),
|
|
12274
|
+
String(readNumber(event.tokenCount) ?? readNumber(compaction?.tokenCount) ?? -1),
|
|
12275
|
+
options.summary ?? "-"
|
|
12276
|
+
];
|
|
12277
|
+
return parts.join("|");
|
|
12278
|
+
}
|
|
11780
12279
|
async function registerMarketplaceProxyTools(api, options, knownNames, proxyNameByToolKey) {
|
|
11781
12280
|
const [catalog, policy] = await Promise.all([
|
|
11782
12281
|
marketplaceToolList({ ...options, refresh: true }),
|
|
@@ -12163,6 +12662,8 @@ ${lines.join(`
|
|
|
12163
12662
|
const SESSION_TURN_TTL_MS = 4 * 60 * 60 * 1000;
|
|
12164
12663
|
const injectedTurns = new Map;
|
|
12165
12664
|
const inFlightTurns = new Set;
|
|
12665
|
+
const beforeCompactions = new Map;
|
|
12666
|
+
const afterCompactions = new Map;
|
|
12166
12667
|
const resolveHookContext = (ctx) => {
|
|
12167
12668
|
if (!isRecord(ctx)) {
|
|
12168
12669
|
return {};
|
|
@@ -12170,9 +12671,100 @@ ${lines.join(`
|
|
|
12170
12671
|
const sessionContext = ctx;
|
|
12171
12672
|
return {
|
|
12172
12673
|
sessionKey: typeof sessionContext?.sessionKey === "string" ? sessionContext.sessionKey : undefined,
|
|
12173
|
-
|
|
12674
|
+
sessionFile: typeof sessionContext?.sessionFile === "string" ? sessionContext.sessionFile.trim() : undefined,
|
|
12675
|
+
agentId: typeof sessionContext?.agentId === "string" ? sessionContext.agentId : undefined,
|
|
12676
|
+
project: firstNonEmptyString(sessionContext.project, sessionContext.cwd, sessionContext.workspace)
|
|
12677
|
+
};
|
|
12678
|
+
};
|
|
12679
|
+
const resolveCompactionSessionKey = (event, ctx) => {
|
|
12680
|
+
const fromEvent = readString(event.sessionKey) ?? readString(event.sessionId);
|
|
12681
|
+
if (fromEvent)
|
|
12682
|
+
return fromEvent;
|
|
12683
|
+
if (ctx.sessionKey)
|
|
12684
|
+
return ctx.sessionKey;
|
|
12685
|
+
return;
|
|
12686
|
+
};
|
|
12687
|
+
const resolveCompactionProject = (event, ctx) => {
|
|
12688
|
+
const compaction = isRecord(event.compaction) ? event.compaction : undefined;
|
|
12689
|
+
const sessionFile = resolveCompactionSessionFile(event, ctx.sessionFile);
|
|
12690
|
+
return firstNonEmptyString(event.project, event.cwd, event.workspace, compaction?.project, compaction?.cwd, compaction?.workspace, ctx.project, readSessionFileProject(sessionFile));
|
|
12691
|
+
};
|
|
12692
|
+
const resolveSessionEndSessionKey = (event, ctx) => {
|
|
12693
|
+
const fromEvent = readString(event.sessionKey) ?? readString(event.sessionId);
|
|
12694
|
+
if (fromEvent)
|
|
12695
|
+
return fromEvent;
|
|
12696
|
+
if (ctx.sessionKey)
|
|
12697
|
+
return ctx.sessionKey;
|
|
12698
|
+
return;
|
|
12699
|
+
};
|
|
12700
|
+
const resolveSessionEndTranscript = (event, ctx) => firstNonEmptyString(event.transcriptPath, event.sessionFile, ctx.sessionFile);
|
|
12701
|
+
const resolveSessionEndProject = (event, ctx) => firstNonEmptyString(event.cwd, event.project, event.workspace, ctx.project);
|
|
12702
|
+
const dedupeCompaction = (map, key) => {
|
|
12703
|
+
const now = Date.now();
|
|
12704
|
+
cleanupTimedMap(map, now, COMPACTION_HOOK_DEDUPE_MS);
|
|
12705
|
+
const seenAt = map.get(key);
|
|
12706
|
+
if (typeof seenAt === "number" && now - seenAt <= COMPACTION_HOOK_DEDUPE_MS) {
|
|
12707
|
+
return true;
|
|
12708
|
+
}
|
|
12709
|
+
map.set(key, now);
|
|
12710
|
+
return false;
|
|
12711
|
+
};
|
|
12712
|
+
const handleBeforeCompaction = async (event, ctx) => {
|
|
12713
|
+
if (!cfg.enabled || !daemonReachable)
|
|
12714
|
+
return;
|
|
12715
|
+
const sessionKey = resolveCompactionSessionKey(event, ctx);
|
|
12716
|
+
const messageCount = typeof event.messageCount === "number" ? event.messageCount : typeof event.compactingCount === "number" ? event.compactingCount : typeof event.compactedCount === "number" ? event.compactedCount : isRecord(event.compaction) && typeof event.compaction.compactingCount === "number" ? event.compaction.compactingCount : isRecord(event.compaction) && typeof event.compaction.compactedCount === "number" ? event.compaction.compactedCount : undefined;
|
|
12717
|
+
const dedupeKey = buildCompactionEventKey(event, {
|
|
12718
|
+
agentId: ctx.agentId,
|
|
12719
|
+
sessionKey
|
|
12720
|
+
});
|
|
12721
|
+
if (dedupeCompaction(beforeCompactions, dedupeKey)) {
|
|
12722
|
+
return;
|
|
12723
|
+
}
|
|
12724
|
+
const result = await onPreCompaction("openclaw", {
|
|
12725
|
+
...opts,
|
|
12726
|
+
sessionKey,
|
|
12727
|
+
messageCount
|
|
12728
|
+
});
|
|
12729
|
+
const parts = [result?.summaryPrompt, result?.guidelines].filter((value) => typeof value === "string" && value.length > 0);
|
|
12730
|
+
if (parts.length === 0) {
|
|
12731
|
+
return;
|
|
12732
|
+
}
|
|
12733
|
+
return {
|
|
12734
|
+
prependContext: parts.join(`
|
|
12735
|
+
|
|
12736
|
+
`)
|
|
12174
12737
|
};
|
|
12175
12738
|
};
|
|
12739
|
+
const handleAfterCompaction = async (event, ctx) => {
|
|
12740
|
+
if (!cfg.enabled || !daemonReachable)
|
|
12741
|
+
return;
|
|
12742
|
+
const sessionKey = resolveCompactionSessionKey(event, ctx);
|
|
12743
|
+
const scopedKey = buildScopedSessionKey(sessionKey, ctx.agentId);
|
|
12744
|
+
if (scopedKey) {
|
|
12745
|
+
injectedTurns.delete(scopedKey);
|
|
12746
|
+
}
|
|
12747
|
+
const sessionFile = resolveCompactionSessionFile(event, ctx.sessionFile);
|
|
12748
|
+
const summary = extractCompactionSummary(event, sessionFile);
|
|
12749
|
+
if (!summary) {
|
|
12750
|
+
api.logger.warn(`signet-memory: compaction summary unavailable, skipping save${sessionFile ? ` (${sessionFile})` : ""}`);
|
|
12751
|
+
return;
|
|
12752
|
+
}
|
|
12753
|
+
const dedupeKey = buildCompactionEventKey(event, {
|
|
12754
|
+
agentId: ctx.agentId,
|
|
12755
|
+
sessionKey,
|
|
12756
|
+
summary
|
|
12757
|
+
});
|
|
12758
|
+
if (dedupeCompaction(afterCompactions, dedupeKey)) {
|
|
12759
|
+
return;
|
|
12760
|
+
}
|
|
12761
|
+
await onCompactionComplete("openclaw", summary, {
|
|
12762
|
+
...opts,
|
|
12763
|
+
agentId: ctx.agentId,
|
|
12764
|
+
project: resolveCompactionProject(event, ctx),
|
|
12765
|
+
sessionKey
|
|
12766
|
+
});
|
|
12767
|
+
};
|
|
12176
12768
|
const ensureSessionStarted = async (event, sessionKey, agentId) => {
|
|
12177
12769
|
if (!sessionKey) {
|
|
12178
12770
|
const now = Date.now();
|
|
@@ -12192,7 +12784,8 @@ ${lines.join(`
|
|
|
12192
12784
|
}
|
|
12193
12785
|
return;
|
|
12194
12786
|
}
|
|
12195
|
-
|
|
12787
|
+
const scopedKey = buildScopedSessionKey(sessionKey, agentId);
|
|
12788
|
+
if (scopedKey && claimedSessions.has(scopedKey)) {
|
|
12196
12789
|
return;
|
|
12197
12790
|
}
|
|
12198
12791
|
const startResult = await onSessionStart("openclaw", {
|
|
@@ -12200,8 +12793,8 @@ ${lines.join(`
|
|
|
12200
12793
|
sessionKey,
|
|
12201
12794
|
agentId
|
|
12202
12795
|
});
|
|
12203
|
-
if (startResult) {
|
|
12204
|
-
claimedSessions.add(
|
|
12796
|
+
if (startResult && scopedKey) {
|
|
12797
|
+
claimedSessions.add(scopedKey);
|
|
12205
12798
|
}
|
|
12206
12799
|
};
|
|
12207
12800
|
const runPromptInjection = async (event, sessionKey, agentId) => {
|
|
@@ -12213,7 +12806,8 @@ ${lines.join(`
|
|
|
12213
12806
|
return;
|
|
12214
12807
|
}
|
|
12215
12808
|
const count = Array.isArray(event.messages) ? event.messages.length : undefined;
|
|
12216
|
-
const
|
|
12809
|
+
const scopedKey = buildScopedSessionKey(sessionKey, agentId);
|
|
12810
|
+
const sig = scopedKey && typeof count === "number" ? `${scopedKey}|${count}` : undefined;
|
|
12217
12811
|
if (sig) {
|
|
12218
12812
|
const now = Date.now();
|
|
12219
12813
|
for (const [k, v] of injectedTurns) {
|
|
@@ -12221,7 +12815,7 @@ ${lines.join(`
|
|
|
12221
12815
|
injectedTurns.delete(k);
|
|
12222
12816
|
}
|
|
12223
12817
|
}
|
|
12224
|
-
if (sig && (inFlightTurns.has(sig) ||
|
|
12818
|
+
if (sig && (inFlightTurns.has(sig) || scopedKey !== undefined && injectedTurns.get(scopedKey)?.count === count)) {
|
|
12225
12819
|
return;
|
|
12226
12820
|
}
|
|
12227
12821
|
if (sig)
|
|
@@ -12239,8 +12833,8 @@ ${lines.join(`
|
|
|
12239
12833
|
if (!result) {
|
|
12240
12834
|
return;
|
|
12241
12835
|
}
|
|
12242
|
-
if (
|
|
12243
|
-
injectedTurns.set(
|
|
12836
|
+
if (scopedKey && typeof count === "number") {
|
|
12837
|
+
injectedTurns.set(scopedKey, { count, at: Date.now() });
|
|
12244
12838
|
}
|
|
12245
12839
|
return buildInjectionResult(result);
|
|
12246
12840
|
};
|
|
@@ -12258,17 +12852,41 @@ ${lines.join(`
|
|
|
12258
12852
|
await ensureSessionStarted(event, sessionKey, agentId);
|
|
12259
12853
|
return runPromptInjection(event, sessionKey, agentId);
|
|
12260
12854
|
});
|
|
12261
|
-
api.on("agent_end", async (
|
|
12855
|
+
api.on("agent_end", async (event, ctx) => {
|
|
12262
12856
|
if (!cfg.enabled)
|
|
12263
12857
|
return;
|
|
12264
|
-
const
|
|
12265
|
-
|
|
12266
|
-
|
|
12267
|
-
|
|
12268
|
-
|
|
12858
|
+
const hook = resolveHookContext(ctx);
|
|
12859
|
+
const sessionKey = resolveSessionEndSessionKey(event, hook);
|
|
12860
|
+
const agentId = hook.agentId;
|
|
12861
|
+
const scopedKey = buildScopedSessionKey(sessionKey, agentId);
|
|
12862
|
+
await onSessionEnd("openclaw", {
|
|
12863
|
+
...opts,
|
|
12864
|
+
agentId,
|
|
12865
|
+
cwd: resolveSessionEndProject(event, hook),
|
|
12866
|
+
sessionId: readString(event.sessionId),
|
|
12867
|
+
sessionKey,
|
|
12868
|
+
transcriptPath: resolveSessionEndTranscript(event, hook)
|
|
12869
|
+
});
|
|
12870
|
+
if (scopedKey) {
|
|
12871
|
+
claimedSessions.delete(scopedKey);
|
|
12872
|
+
injectedTurns.delete(scopedKey);
|
|
12269
12873
|
}
|
|
12270
12874
|
return;
|
|
12271
12875
|
});
|
|
12876
|
+
api.on("before_compaction", async (event, ctx) => {
|
|
12877
|
+
return handleBeforeCompaction(event, resolveHookContext(ctx));
|
|
12878
|
+
});
|
|
12879
|
+
api.on("after_compaction", async (event, ctx) => {
|
|
12880
|
+
await handleAfterCompaction(event, resolveHookContext(ctx));
|
|
12881
|
+
return;
|
|
12882
|
+
});
|
|
12883
|
+
api.on("session:compact:before", async (event, ctx) => {
|
|
12884
|
+
return handleBeforeCompaction(event, resolveHookContext(ctx));
|
|
12885
|
+
});
|
|
12886
|
+
api.on("session:compact:after", async (event, ctx) => {
|
|
12887
|
+
await handleAfterCompaction(event, resolveHookContext(ctx));
|
|
12888
|
+
return;
|
|
12889
|
+
});
|
|
12272
12890
|
api.registerService({
|
|
12273
12891
|
id: "signet-memory-openclaw",
|
|
12274
12892
|
start() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signetai/signet-memory-openclaw",
|
|
3
|
-
"version": "0.77.
|
|
3
|
+
"version": "0.77.6",
|
|
4
4
|
"description": "Signet adapter for OpenClaw — runtime plugin for AI agent memory",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"@sinclair/typebox": "0.34.47"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@signet/core": "0.77.
|
|
39
|
+
"@signet/core": "0.77.6",
|
|
40
40
|
"@types/node": "^22.0.0"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|