Quản lý Session

OpenClaw coi một session trò chuyện trực tiếp cho mỗi agent là chính. Các cuộc trò chuyện trực tiếp được gộp thành agent:<agentId>:<mainKey> (mặc định là main), trong khi các cuộc trò chuyện nhóm/channel có khóa riêng. session.mainKey sẽ được tuân thủ.

Dùng session.dmScope để kiểm soát cách tin nhắn trực tiếp được nhóm lại:

  • main (mặc định): tất cả DM dùng chung session chính để duy trì tính liên tục.
  • per-peer: tách biệt theo id người gửi trên các channel.
  • per-channel-peer: tách biệt theo channel + người gửi (khuyên dùng cho hộp thư đa người dùng).
  • per-account-channel-peer: tách biệt theo tài khoản + channel + người gửi (khuyên dùng cho hộp thư đa tài khoản). Dùng session.identityLinks để ánh xạ các peer id có tiền tố provider (ví dụ telegram:123) thành một danh tính chuẩn để cùng một người có thể chia sẻ session DM trên các channel khi dùng per-peer, per-channel-peer, hoặc per-account-channel-peer.

Gateway là nguồn chân lý

Tất cả trạng thái session thuộc sở hữu của gateway (OpenClaw “chủ”). Các UI client (ứng dụng macOS, WebChat, v.v.) phải truy vấn gateway để lấy danh sách session và số lượng token thay vì đọc file local.

  • chế độ remote, session store mà các bạn quan tâm nằm trên máy chủ gateway từ xa, không phải trên Mac của bạn.
  • Số lượng token hiển thị trong UI đến từ các trường store của gateway (inputTokens, outputTokens, totalTokens, contextTokens). Client không parse transcript JSONL để “sửa” tổng số.

Nơi lưu trữ trạng thái

  • Trên máy chủ gateway:
    • File store: ~/.openclaw/agents/<agentId>/sessions/sessions.json (mỗi agent).
  • Transcript: ~/.openclaw/agents/<agentId>/sessions/<SessionId>.jsonl (session topic Telegram dùng .../<SessionId>-topic-<threadId>.jsonl).
  • Store là một map sessionKey -> { sessionId, updatedAt, ... }. Xóa các entry là an toàn; chúng sẽ được tạo lại khi cần.
  • Các entry nhóm có thể bao gồm displayName, channel, subject, room, và space để gắn nhãn session trong UI.
  • Các entry session bao gồm metadata origin (nhãn + gợi ý routing) để UI có thể giải thích session đến từ đâu.
  • OpenClaw không đọc các thư mục session Pi/Tau cũ.

Session pruning

OpenClaw cắt bỏ kết quả tool cũ khỏi context trong bộ nhớ ngay trước khi gọi LLM theo mặc định. Điều này không ghi đè lịch sử JSONL. Xem /concepts/session-pruning.

Pre-compaction memory flush

Khi một session gần đến auto-compaction, OpenClaw có thể chạy một lượt memory flush im lặng để nhắc model ghi các ghi chú bền vững vào đĩa. Điều này chỉ chạy khi workspace có thể ghi được. Xem MemoryCompaction.

Ánh xạ transport → khóa session

  • Trò chuyện trực tiếp tuân theo session.dmScope (mặc định main).
    • main: agent:<agentId>:<mainKey> (tính liên tục trên các thiết bị/channel).
      • Nhiều số điện thoại và channel có thể ánh xạ đến cùng một khóa chính của agent; chúng hoạt động như các transport vào một cuộc trò chuyện.
    • per-peer: agent:<agentId>:dm:<peerId>.
    • per-channel-peer: agent:<agentId>:<channel>:dm:<peerId>.
    • per-account-channel-peer: agent:<agentId>:<channel>:<accountId>:dm:<peerId> (accountId mặc định là default).
    • Nếu session.identityLinks khớp với peer id có tiền tố provider (ví dụ telegram:123), khóa chuẩn sẽ thay thế <peerId> để cùng một người chia sẻ session trên các channel.
  • Trò chuyện nhóm tách biệt trạng thái: agent:<agentId>:<channel>:group:<id> (phòng/channel dùng agent:<agentId>:<channel>:channel:<id>).
    • Các topic diễn đàn Telegram thêm :topic:<threadId> vào id nhóm để tách biệt.
    • Các khóa group:<id> cũ vẫn được nhận diện để migration.
  • Các context đến có thể vẫn dùng group:<id>; channel được suy ra từ Provider và chuẩn hóa thành dạng agent:<agentId>:<channel>:group:<id> chuẩn.
  • Các nguồn khác:
    • Cron job: cron:<job.id>
    • Webhook: hook:<uuid> (trừ khi được đặt rõ ràng bởi hook)
    • Node run: node-<nodeId>

Vòng đời

  • Chính sách reset: session được tái sử dụng cho đến khi hết hạn, và việc hết hạn được đánh giá ở tin nhắn đến tiếp theo.
  • Reset hàng ngày: mặc định là 4:00 sáng giờ địa phương trên máy chủ gateway. Một session bị cũ khi lần cập nhật cuối cùng của nó sớm hơn thời điểm reset hàng ngày gần nhất.
  • Reset khi idle (tùy chọn): idleMinutes thêm một cửa sổ idle trượt. Khi cả reset hàng ngày và idle được cấu hình, cái nào hết hạn trước sẽ buộc tạo session mới.
  • Legacy idle-only: nếu các bạn đặt session.idleMinutes mà không có bất kỳ config session.reset/resetByType nào, OpenClaw sẽ ở chế độ idle-only để tương thích ngược.
  • Ghi đè theo loại (tùy chọn): resetByType cho phép các bạn ghi đè chính sách cho session dm, group, và thread (thread = thread Slack/Discord, topic Telegram, thread Matrix khi được cung cấp bởi connector).
  • Ghi đè theo channel (tùy chọn): resetByChannel ghi đè chính sách reset cho một channel (áp dụng cho tất cả loại session của channel đó và ưu tiên hơn reset/resetByType).
  • Trigger reset: lệnh chính xác /new hoặc /reset (cộng thêm bất kỳ lệnh nào trong resetTriggers) bắt đầu một session id mới và chuyển phần còn lại của tin nhắn qua. /new <model> chấp nhận alias model, provider/model, hoặc tên provider (khớp mờ) để đặt model session mới. Nếu /new hoặc /reset được gửi một mình, OpenClaw chạy một lượt chào ngắn để xác nhận reset.
  • Reset thủ công: xóa các khóa cụ thể khỏi store hoặc xóa transcript JSONL; tin nhắn tiếp theo sẽ tạo lại chúng.
  • Các cron job tách biệt luôn tạo sessionId mới cho mỗi lần chạy (không tái sử dụng idle).

Chính sách gửi (tùy chọn)

Chặn gửi cho các loại session cụ thể mà không cần liệt kê từng id.

{
  session: {
    sendPolicy: {
      rules: [
        { action: "deny", match: { channel: "discord", chatType: "group" } },
        { action: "deny", match: { keyPrefix: "cron:" } },
      ],
      default: "allow",
    },
  },
}

Ghi đè runtime (chỉ owner):

  • /send on → cho phép cho session này
  • /send off → từ chối cho session này
  • /send inherit → xóa ghi đè và dùng quy tắc config Gửi các lệnh này như tin nhắn độc lập để chúng được đăng ký.

Cấu hình (ví dụ đổi tên tùy chọn)

// ~/.openclaw/openclaw.json
{
  session: {
    scope: "per-sender", // giữ các khóa nhóm riêng biệt
    dmScope: "main", // tính liên tục DM (đặt per-channel-peer/per-account-channel-peer cho hộp thư chia sẻ)
    identityLinks: {
      alice: ["telegram:123456789", "discord:987654321012345678"],
    },
    reset: {
      // Mặc định: mode=daily, atHour=4 (giờ địa phương máy chủ gateway).
      // Nếu các bạn cũng đặt idleMinutes, cái nào hết hạn trước sẽ thắng.
      mode: "daily",
      atHour: 4,
      idleMinutes: 120,
    },
    resetByType: {
      thread: { mode: "daily", atHour: 4 },
      dm: { mode: "idle", idleMinutes: 240 },
      group: { mode: "idle", idleMinutes: 120 },
    },
    resetByChannel: {
      discord: { mode: "idle", idleMinutes: 10080 },
    },
    resetTriggers: ["/new", "/reset"],
    store: "~/.openclaw/agents/{agentId}/sessions/sessions.json",
    mainKey: "main",
  },
}

Kiểm tra

  • openclaw status — hiển thị đường dẫn store và các session gần đây.
  • openclaw sessions --json — dump tất cả entry (lọc bằng --active <minutes>).
  • openclaw gateway call sessions.list --params '{}' — lấy session từ gateway đang chạy (dùng --url/--token để truy cập gateway từ xa).
  • Gửi /status như một tin nhắn độc lập trong chat để xem agent có thể truy cập được không, bao nhiêu context session đang được dùng, các toggle thinking/verbose hiện tại, và khi nào thông tin đăng nhập WhatsApp web của các bạn được làm mới lần cuối (giúp phát hiện nhu cầu liên kết lại).
  • Gửi /context list hoặc /context detail để xem có gì trong system prompt và các file workspace được inject (và những đóng góp context lớn nhất).
  • Gửi /stop như một tin nhắn độc lập để hủy lượt chạy hiện tại, xóa các followup đang chờ cho session đó, và dừng bất kỳ lượt chạy sub-agent nào được sinh ra từ nó (phản hồi bao gồm số lượng đã dừng).
  • Gửi /compact (hướng dẫn tùy chọn) như một tin nhắn độc lập để tóm tắt context cũ hơn và giải phóng không gian cửa sổ. Xem /concepts/compaction.
  • Các transcript JSONL có thể được mở trực tiếp để xem lại các lượt đầy đủ.

Mẹo

  • Giữ khóa chính dành riêng cho traffic 1:1; để các nhóm giữ khóa riêng của chúng.
  • Khi tự động hóa dọn dẹp, xóa các khóa riêng lẻ thay vì toàn bộ store để bảo toàn context ở nơi khác.

Metadata nguồn gốc session

Mỗi entry session ghi lại nơi nó đến từ đâu (cố gắng tốt nhất) trong origin:

  • label: nhãn con người (được giải quyết từ nhãn cuộc trò chuyện + chủ đề/channel nhóm)
  • provider: id channel chuẩn hóa (bao gồm extension)
  • from/to: id routing thô từ envelope đến
  • accountId: id tài khoản provider (khi đa tài khoản)
  • threadId: id thread/topic khi channel hỗ trợ Các trường origin được điền cho tin nhắn trực tiếp, channel, và nhóm. Nếu một connector chỉ cập nhật routing gửi (ví dụ, để giữ session chính DM mới), nó vẫn nên cung cấp context đến để session giữ metadata giải thích của nó. Extension có thể làm điều này bằng cách gửi ConversationLabel, GroupSubject, GroupChannel, GroupSpace, và SenderName trong context đến và gọi recordSessionMetaFromInbound (hoặc truyền cùng context đến updateLastRoute).