惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
G
GRAHAM CLULEY
P
Privacy & Cybersecurity Law Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
宝玉的分享
宝玉的分享
P
Proofpoint News Feed
H
Help Net Security
V
Visual Studio Blog
阮一峰的网络日志
阮一峰的网络日志
C
Cisco Blogs
人人都是产品经理
人人都是产品经理
Know Your Adversary
Know Your Adversary
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Recorded Future
Recorded Future
I
Intezer
罗磊的独立博客
T
The Exploit Database - CXSecurity.com
Blog — PlanetScale
Blog — PlanetScale
Malwarebytes
Malwarebytes
Spread Privacy
Spread Privacy
T
Tor Project blog
V
Vulnerabilities – Threatpost
云风的 BLOG
云风的 BLOG
腾讯CDC
B
Blog RSS Feed
Stack Overflow Blog
Stack Overflow Blog
F
Future of Privacy Forum
MyScale Blog
MyScale Blog
Latest news
Latest news
IT之家
IT之家
MongoDB | Blog
MongoDB | Blog
The Hacker News
The Hacker News
S
Securelist
博客园 - 【当耐特】
C
CXSECURITY Database RSS Feed - CXSecurity.com
T
Threat Research - Cisco Blogs
Jina AI
Jina AI
Cisco Talos Blog
Cisco Talos Blog
B
Blog
博客园 - 三生石上(FineUI控件)
Last Week in AI
Last Week in AI
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
M
MIT News - Artificial intelligence
V
V2EX
D
Darknet – Hacking Tools, Hacker News & Cyber Security
The Cloudflare Blog
The GitHub Blog
The GitHub Blog
博客园 - 聂微东
F
Full Disclosure
C
CERT Recently Published Vulnerability Notes

Recent Commits to openclaw:main

fix(agents): classify auth HTML provider responses (#79900) fix(gateway): allow bearer-auth session history reads (#81815) fix(installer): handle headless onboarding tty fix(exec): protect pathPrepend against posix login-shell RC overrides… test: fix environment sensitivity in resolveNpmCommandInvocation test… · openclaw/openclaw@faf96ff fix(auth): load legacy Codex OAuth sidecars in embedded secrets-runti… Fix/codex deactivated workspace failover (#55893) fix(codex): demote plugin thread eligibility log · openclaw/openclaw@1d5b5db address review v2: workspace scope, warm generation guard, plugin rel… · openclaw/openclaw@c452a1e address review: scope short-circuit by caller auth context + rewarm o… · openclaw/openclaw@01087cb test(model-provider-auth): cover prepared-state short-circuit and clear · openclaw/openclaw@180cecd fix(models): reset warmed provider auth on hot reload · openclaw/openclaw@aef8d17 perf(models): pre-warm provider auth state at gateway startup · openclaw/openclaw@4f80cc1 address review v3: invalidate prepared map on auth-profile logout + d… · openclaw/openclaw@7ddcca6 fix(qa-lab): rename codex lifecycle fixtures to match knip ignore pat… · openclaw/openclaw@ebd8b00 test(gateway): relax e2e node status waits · openclaw/openclaw@b25a0d0 fix #84745: scope Google preview model normalization to Google provid… · openclaw/openclaw@7d5afcb test(qa-lab): cover codex plugin lifecycle fixtures · openclaw/openclaw@bbf3eec fix(tests): allow slower kitchen sink installs · openclaw/openclaw@ec0cf9a revert(qa-lab): remove scenario github traceability metadata · openclaw/openclaw@46c8864 fix(docker): prune omitted plugin runtime deps fix(auth): skip OAuth refresh adapter when credential has no refresh … test(qa-lab): cover update package sentinel · openclaw/openclaw@178e510 fix(json): retry on transient File changed during read race condition… fix(status): add gateway delivery health telemetry (#85016) · openclaw/openclaw@5955f35 test(qa-lab): trace scenario issue evidence · openclaw/openclaw@efb7e47 fix(sessions): preserve compatible auth overrides (#85014) · openclaw/openclaw@b33deb4 ci(qa): publish soak parity artifacts fix(qa): keep searchable tool coverage report-only test(e2e): isolate kitchen sink rpc gateway fix(ollama): allow Orb host local auth (#84999) · openclaw/openclaw@277a4b6 test(qa-lab): add personal failure recovery scenario · openclaw/openclaw@229323d ci: tune crabbox developer image config feat(qa-lab): add jsonl replay harness · openclaw/openclaw@cf06578 fix(codex): beta blocker - keep context engine on canonical session k… · openclaw/openclaw@66dcc4e chore(release): refresh generated baselines · openclaw/openclaw@1b1580c fix(openshell): use NVIDIA CLI contract · openclaw/openclaw@e72f601 docs(release): prefer 1Password provider preflight Policy: add model, network, and MCP conformance checks (#80783) · openclaw/openclaw@6dbd5bd fix(agents): fence embedded session writes refactor: remove sender owner tool gating · openclaw/openclaw@02182d5 docs: remove stale owner tool wording test: update command auth expectations · openclaw/openclaw@95eac52 fix(xai): keep OAuth URL clickable (#84927) · openclaw/openclaw@159b300 Fix stale WebChat typing indicator after terminal session patch (#84565) docs: document rejected autoreview findings · openclaw/openclaw@c49647e docs(changelog): note VAPID subject fix · openclaw/openclaw@db606a8 perf(plugins): reuse compatible gateway startup registry · openclaw/openclaw@d2ad7d6 test: cover dispatch registry reuse caller · openclaw/openclaw@b248b48 docs: add plugin registry reuse changelog · openclaw/openclaw@6ccca4a fix(tests): wrap kitchen sink pnpm runner fix(agents): cap heartbeat context hint fallback · openclaw/openclaw@04061bc chore(deadcode): dedupe repeated helpers · openclaw/openclaw@88c49f9 perf(cli): cache stable subcommand help (#84786) · openclaw/openclaw@f39f56a fix(ollama): preserve tool call ids [AI-assisted] (#84855) · openclaw/openclaw@2000227 fix: align remaining copyright notice · openclaw/openclaw@f43e83c fix(config): append numeric bound hints to ceiling/floor validation e… · openclaw/openclaw@8a8f9dc fix(qa): enable private self-check runtime · openclaw/openclaw@0fb1de5 fix(diffs): replace iconMarkup string with ToolbarIconName enum to el… · openclaw/openclaw@b7f9bf5 fix: update mac copyright owner fix(agents): normalize openapi tool schemas · openclaw/openclaw@ec67290 fix(memory): stop recall tracking when dreaming is disabled · openclaw/openclaw@c89632b fix(diagnostics-otel): suppress exporter rejection crashes (#84881) perf: speed up secrets and nodes help startup (#84818) · openclaw/openclaw@233765b docs: add PDF timeout changelog · openclaw/openclaw@e3b77d6 fix(pdf): bound remote body reads [Fix] Reject slow node event sends (#84387) fix(doctor): detect Codex bwrap namespace denials · openclaw/openclaw@43c6c26 fix(update): prune stale local bundled plugin shadows · openclaw/openclaw@4a360ac ci: add live Codex plugin release check · openclaw/openclaw@3eb2d64 fix(slack): suppress reasoning reply payloads (#84322) chore: update vite · openclaw/openclaw@ec7495c chore: update dependencies · openclaw/openclaw@ec10d12 fix(config): validate browser sandbox bind sources [AI] (#84799) · openclaw/openclaw@3cc8b2a doctor: constrain legacy plugin cleanup paths [AI] (#84801) Fix Telegram isolated polling stall watchdog (#84861) · openclaw/openclaw@40db92f ci(release): keep non-waiting clawhub publish best effort fix(docker): keep prune store warmup before offline stage · openclaw/openclaw@1e8d966 ci(release): require resolved target before child dispatch · openclaw/openclaw@2fd02c2 fix(docker): keep runtime prune offline · openclaw/openclaw@a329b9e ci(release): streamline beta publish verification · openclaw/openclaw@1c5fda1 ci(release): preserve direct repair publishes · openclaw/openclaw@0604d25 ci(release): keep focused validation reruns independent · openclaw/openclaw@624d920 [Fix] Keep node systemd tokens out of unit files (#84815) fix: reject symlinked whatsapp creds · openclaw/openclaw@194f078 fix(whatsapp): guard credential atomic writes refactor(whatsapp): use async fs-safe credential checks · openclaw/openclaw@9ec9fbf fix(doctor): clear stale runtime override pins (#84221) fix(agents): disable pi-coding-agent auto-retry to prevent tool call … fix(trajectory): tolerate partial skill snapshot entries in support c… · openclaw/openclaw@c9b6a8b fix(ui): widen settings personal card · openclaw/openclaw@3156d94 fix(agents): log pre-prompt compaction fits decisions (#84676) · openclaw/openclaw@79be940 fix(memory-core): allow bounded dreaming session cleanup (#84802) · openclaw/openclaw@0671a2a perf(cli): lazy-load agents actions for help (#84483) · openclaw/openclaw@168f8a7 Skip empty sherpa structured transcripts (#84667) · openclaw/openclaw@46030f5 feat: support git and local skill installs (#84793) · openclaw/openclaw@c031274 Policy: add tool metadata conformance (#80056) fix(doctor): warn when sandbox hides MCP tools (#84742) · openclaw/openclaw@6745fe8 perf(cli): speed up onboarding help startup (#84488) · openclaw/openclaw@2c0c9c9 perf: isolate doctor core check tests (#84493) · openclaw/openclaw@2585249
refactor(gateway): remove unused readLastMessagePreviewFromTranscript… · openclaw/openclaw@9b7e431
medns · 2026-05-22 · via Recent Commits to openclaw:main

@@ -9,7 +9,6 @@ import { clearSessionTranscriptIndexCache } from "./session-transcript-index.fs.

99

import {

1010

archiveSessionTranscripts,

1111

readFirstUserMessageFromTranscript,

12-

readLastMessagePreviewFromTranscript,

1312

readLatestSessionUsageFromTranscript,

1413

readLatestSessionUsageFromTranscriptAsync,

1514

readLatestRecentSessionUsageFromTranscriptAsync,

@@ -275,176 +274,6 @@ describe("readFirstUserMessageFromTranscript", () => {

275274

});

276275

});

277276278-

describe("readLastMessagePreviewFromTranscript", () => {

279-

let tmpDir: string;

280-

let storePath: string;

281-282-

registerTempSessionStore("openclaw-session-fs-test-", (nextTmpDir, nextStorePath) => {

283-

tmpDir = nextTmpDir;

284-

storePath = nextStorePath;

285-

});

286-287-

test("returns null for empty file", () => {

288-

const sessionId = "test-last-empty";

289-

const transcriptPath = path.join(tmpDir, `${sessionId}.jsonl`);

290-

fs.writeFileSync(transcriptPath, "", "utf-8");

291-292-

const result = readLastMessagePreviewFromTranscript(sessionId, storePath);

293-

expect(result).toBeNull();

294-

});

295-296-

test.each([

297-

{

298-

sessionId: "test-last-user",

299-

lines: [

300-

JSON.stringify({ message: { role: "user", content: "First user" } }),

301-

JSON.stringify({ message: { role: "assistant", content: "First assistant" } }),

302-

JSON.stringify({ message: { role: "user", content: "Last user message" } }),

303-

],

304-

expected: "Last user message",

305-

},

306-

{

307-

sessionId: "test-last-assistant",

308-

lines: [

309-

JSON.stringify({ message: { role: "user", content: "User question" } }),

310-

JSON.stringify({ message: { role: "assistant", content: "Final assistant reply" } }),

311-

],

312-

expected: "Final assistant reply",

313-

},

314-

] as const)(

315-

"returns the last user or assistant message from transcript for $sessionId",

316-

({ sessionId, lines, expected }) => {

317-

const transcriptPath = path.join(tmpDir, `${sessionId}.jsonl`);

318-

fs.writeFileSync(transcriptPath, lines.join("\n"), "utf-8");

319-

const result = readLastMessagePreviewFromTranscript(sessionId, storePath);

320-

expect(result).toBe(expected);

321-

},

322-

);

323-324-

test("skips system messages to find last user/assistant", () => {

325-

const sessionId = "test-last-skip-system";

326-

const transcriptPath = path.join(tmpDir, `${sessionId}.jsonl`);

327-

const lines = [

328-

JSON.stringify({ message: { role: "user", content: "Real last" } }),

329-

JSON.stringify({ message: { role: "system", content: "System at end" } }),

330-

];

331-

fs.writeFileSync(transcriptPath, lines.join("\n"), "utf-8");

332-333-

const result = readLastMessagePreviewFromTranscript(sessionId, storePath);

334-

expect(result).toBe("Real last");

335-

});

336-337-

test("returns null when no user/assistant messages exist", () => {

338-

const sessionId = "test-last-no-match";

339-

const transcriptPath = path.join(tmpDir, `${sessionId}.jsonl`);

340-

const lines = [

341-

JSON.stringify({ type: "session", version: 1, id: sessionId }),

342-

JSON.stringify({ message: { role: "system", content: "Only system" } }),

343-

];

344-

fs.writeFileSync(transcriptPath, lines.join("\n"), "utf-8");

345-346-

const result = readLastMessagePreviewFromTranscript(sessionId, storePath);

347-

expect(result).toBeNull();

348-

});

349-350-

test("handles malformed JSON lines gracefully (last preview)", () => {

351-

const sessionId = "test-last-malformed";

352-

const transcriptPath = path.join(tmpDir, `${sessionId}.jsonl`);

353-

const lines = [

354-

JSON.stringify({ message: { role: "user", content: "Valid first" } }),

355-

"not valid json at end",

356-

];

357-

fs.writeFileSync(transcriptPath, lines.join("\n"), "utf-8");

358-359-

const result = readLastMessagePreviewFromTranscript(sessionId, storePath);

360-

expect(result).toBe("Valid first");

361-

});

362-363-

test.each([

364-

{

365-

sessionId: "test-last-array",

366-

message: {

367-

role: "assistant",

368-

content: [{ type: "text", text: "Array content response" }],

369-

},

370-

expected: "Array content response",

371-

},

372-

{

373-

sessionId: "test-last-output-text",

374-

message: {

375-

role: "assistant",

376-

content: [{ type: "output_text", text: "Output text response" }],

377-

},

378-

expected: "Output text response",

379-

},

380-

] as const)(

381-

"handles array/output_text content format for $sessionId",

382-

({ sessionId, message, expected }) => {

383-

const transcriptPath = path.join(tmpDir, `${sessionId}.jsonl`);

384-

fs.writeFileSync(transcriptPath, JSON.stringify({ message }), "utf-8");

385-

const result = readLastMessagePreviewFromTranscript(sessionId, storePath);

386-

expect(result, sessionId).toBe(expected);

387-

},

388-

);

389-390-

test("skips empty content to find previous message", () => {

391-

const sessionId = "test-last-skip-empty";

392-

const transcriptPath = path.join(tmpDir, `${sessionId}.jsonl`);

393-

const lines = [

394-

JSON.stringify({ message: { role: "assistant", content: "Has content" } }),

395-

JSON.stringify({ message: { role: "user", content: "" } }),

396-

];

397-

fs.writeFileSync(transcriptPath, lines.join("\n"), "utf-8");

398-399-

const result = readLastMessagePreviewFromTranscript(sessionId, storePath);

400-

expect(result).toBe("Has content");

401-

});

402-403-

test("reads from end of large file (16KB window)", () => {

404-

const sessionId = "test-last-large";

405-

const transcriptPath = path.join(tmpDir, `${sessionId}.jsonl`);

406-

const padding = JSON.stringify({ message: { role: "user", content: "x".repeat(500) } });

407-

const lines: string[] = [];

408-

for (let i = 0; i < 30; i++) {

409-

lines.push(padding);

410-

}

411-

lines.push(JSON.stringify({ message: { role: "assistant", content: "Last in large file" } }));

412-

fs.writeFileSync(transcriptPath, lines.join("\n"), "utf-8");

413-414-

const result = readLastMessagePreviewFromTranscript(sessionId, storePath);

415-

expect(result).toBe("Last in large file");

416-

});

417-418-

test("handles valid UTF-8 content", () => {

419-

const sessionId = "test-last-utf8";

420-

const transcriptPath = path.join(tmpDir, `${sessionId}.jsonl`);

421-

const validLine = JSON.stringify({

422-

message: { role: "user", content: "Valid UTF-8: 你好世界 🌍" },

423-

});

424-

fs.writeFileSync(transcriptPath, validLine, "utf-8");

425-426-

const result = readLastMessagePreviewFromTranscript(sessionId, storePath);

427-

expect(result).toBe("Valid UTF-8: 你好世界 🌍");

428-

});

429-430-

test("strips inline directives from last preview text", () => {

431-

const sessionId = "test-last-strip-inline-directives";

432-

const transcriptPath = path.join(tmpDir, `${sessionId}.jsonl`);

433-

const lines = [

434-

JSON.stringify({

435-

message: {

436-

role: "assistant",

437-

content: "Hello [[reply_to_current]] world [[audio_as_voice]]",

438-

},

439-

}),

440-

];

441-

fs.writeFileSync(transcriptPath, lines.join("\n"), "utf-8");

442-443-

const result = readLastMessagePreviewFromTranscript(sessionId, storePath);

444-

expect(result).toBe("Hello world");

445-

});

446-

});

447-448277

describe("shared transcript read behaviors", () => {

449278

let tmpDir: string;

450279

let storePath: string;

@@ -456,13 +285,11 @@ describe("shared transcript read behaviors", () => {

456285457286

test("returns null for missing transcript files", () => {

458287

expect(readFirstUserMessageFromTranscript("missing-session", storePath)).toBeNull();

459-

expect(readLastMessagePreviewFromTranscript("missing-session", storePath)).toBeNull();

460288

});

461289462290

test("uses sessionFile overrides when provided", () => {

463291

const sessionId = "test-shared-custom";

464292

const firstPath = path.join(tmpDir, "custom-first.jsonl");

465-

const lastPath = path.join(tmpDir, "custom-last.jsonl");

466293467294

fs.writeFileSync(

468295

firstPath,

@@ -472,37 +299,22 @@ describe("shared transcript read behaviors", () => {

472299

].join("\n"),

473300

"utf-8",

474301

);

475-

fs.writeFileSync(

476-

lastPath,

477-

JSON.stringify({ message: { role: "assistant", content: "Custom file last" } }),

478-

"utf-8",

479-

);

480302481303

expect(readFirstUserMessageFromTranscript(sessionId, storePath, firstPath)).toBe(

482304

"Custom file message",

483305

);

484-

expect(readLastMessagePreviewFromTranscript(sessionId, storePath, lastPath)).toBe(

485-

"Custom file last",

486-

);

487306

});

488307489308

test("trims whitespace in extracted previews", () => {

490309

const firstSessionId = "test-shared-first-trim";

491-

const lastSessionId = "test-shared-last-trim";

492310493311

fs.writeFileSync(

494312

path.join(tmpDir, `${firstSessionId}.jsonl`),

495313

JSON.stringify({ message: { role: "user", content: " Padded message " } }),

496314

"utf-8",

497315

);

498-

fs.writeFileSync(

499-

path.join(tmpDir, `${lastSessionId}.jsonl`),

500-

JSON.stringify({ message: { role: "assistant", content: " Padded response " } }),

501-

"utf-8",

502-

);

503316504317

expect(readFirstUserMessageFromTranscript(firstSessionId, storePath)).toBe("Padded message");

505-

expect(readLastMessagePreviewFromTranscript(lastSessionId, storePath)).toBe("Padded response");

506318

});

507319

});

508320