mcpField
S
session-logs

session-logs

github.com/openclawエージェントワークフロー393.3k5.0k 回インストール今日更新
リポジトリ

session-logs について

session-logsは、OpenClawのセッションJSONLファイル内の会話履歴を検索するスキルです。アーカイブを含む過去の文脈や、メッセージ、セッション統計を調べるコマンド例を示します。

主な機能

  1. 01会話履歴の検索
  2. 02リセット・削除済みアーカイブの対象化
  3. 03ユーザーまたはアシスタントの発言抽出
  4. 04セッションの発言数と費用の集計

活用シーン

  1. 01以前の会話内容を探す
  2. 02日付でセッションを絞り込む
  3. 03アシスタントの返信から語句を検索
  4. 04セッション費用と発言数を集計

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/openclaw/openclaw --skill session-logs

インストール後、Claude Code で/session-logsを入力して読み込まれたか確認します。

詳細

session-logs

セッション JSONL ファイルに保存された完全な会話履歴を検索します。ユーザーが古い会話や親会話を参照したり、以前に何が話されたかを尋ねたりした場合に使用します。

トリガー

ユーザーが過去のチャット、親会話、またはメモリファイルにない履歴コンテキストについて尋ねた場合に、このスキルを使用します。

場所

セッションログはアクティブな状態ディレクトリの下にあります: $OPENCLAW_STATE_DIR/agents/<agentId>/sessions/(デフォルト: ~/.openclaw/agents/<agentId>/sessions/)。 システムプロンプトの Runtime 行にある agent=<id> の値を使用します。

  • sessions.json - セッションキーをセッション ID にマッピングするインデックス
  • <session-id>.jsonl - セッションごとの完全な会話記録
  • <session-id>.jsonl.reset.<timestamp>Z - /new または /reset によってアーカイブされた会話記録
  • <session-id>.jsonl.deleted.<timestamp>Z - セッションが削除されたときにアーカイブされた会話記録

履歴を検索する際は、アーカイブされたバリアント(.reset.*、.deleted.*)も含めてください。それらには 実際の会話内容が依然として含まれています。以下の単純な glob の例では、アクティブな *.jsonl ファイルしか 対象になりません。完全な履歴が必要な場合は「アーカイブされた会話記録を含める」スニペットを使用してください。

構造

各 .jsonl ファイルには次の要素を持つメッセージが含まれます:

  • type: "session"(メタデータ)または "message"
  • timestamp: ISO タイムスタンプ
  • message.role: "user"、"assistant"、または "toolResult"
  • message.content[]: テキスト、思考、またはツール呼び出し(人間が読める内容には type=="text" でフィルタリング)
  • message.usage.cost.total: 応答ごとのコスト

一般的なクエリ

アーカイブされた会話記録を含める(.reset.*、.deleted.*)
# Bash helper that emits every searchable transcript path — active and archived.
# Saves and restores `nullglob` locally so callers' shell options aren't disturbed.
AGENT_ID="<agentId>"
SESSION_DIR="${OPENCLAW_STATE_DIR:-$HOME/.openclaw}/agents/$AGENT_ID/sessions"
list_session_transcripts() {
  local _nullglob_state
  _nullglob_state=$(shopt -p nullglob 2>/dev/null)
  shopt -s nullglob
  for f in "$SESSION_DIR"/*.jsonl \
           "$SESSION_DIR"/*.jsonl.reset.*Z \
           "$SESSION_DIR"/*.jsonl.deleted.*Z; do
    [ -f "$f" ] && printf '%s\n' "$f"
  done
  eval "$_nullglob_state"
}

以下で単純な *.jsonl glob が示されている箇所では、アーカイブされたセッションを含める必要がある場合、 list_session_transcripts(または同等の find 呼び出し)を使用してください:

find "$SESSION_DIR" -maxdepth 1 -type f \
  \( -name '*.jsonl' -o -name '*.jsonl.reset.*Z' -o -name '*.jsonl.deleted.*Z' \) -print
日付とサイズで全セッションを一覧表示する
AGENT_ID="<agentId>"
SESSION_DIR="${OPENCLAW_STATE_DIR:-$HOME/.openclaw}/agents/$AGENT_ID/sessions"
for f in "$SESSION_DIR"/*.jsonl; do
  date=$(head -1 "$f" | jq -r '.timestamp' | cut -dT -f1)
  size=$(ls -lh "$f" | awk '{print $5}')
  echo "$date $size $(basename $f)"
done | sort -r

ヒント: 一覧にアーカイブされた .reset / .deleted ファイルも含めたい場合は、for f in ... の行を list_session_transcripts(上記のスニペットを参照)に対する while-read に置き換えてください。 while-read パターンは、スペースやその他の IFS 文字を含むパスでも安全です:

while IFS= read -r f; do
  date=$(head -1 "$f" | jq -r '.timestamp' | cut -dT -f1)
  size=$(ls -lh "$f" | awk '{print $5}')
  echo "$date $size $(basename "$f")"
done < <(list_session_transcripts) | sort -r
特定の日のセッションを検索する
AGENT_ID="<agentId>"
SESSION_DIR="${OPENCLAW_STATE_DIR:-$HOME/.openclaw}/agents/$AGENT_ID/sessions"
for f in "$SESSION_DIR"/*.jsonl; do
  head -1 "$f" | jq -r '.timestamp' | grep -q "2026-01-06" && echo "$f"
done
セッションからユーザーメッセージを抽出する
jq -r 'select(.message.role == "user") | .message.content[]? | select(.type == "text") | .text' <session>.jsonl
アシスタントの応答でキーワードを検索する
jq -r 'select(.message.role == "assistant") | .message.content[]? | select(.type == "text") | .text' <session>.jsonl | rg -i "keyword"
セッションの合計コストを取得する
jq -s '[.[] | .message.usage.cost.total // 0] | add' <session>.jsonl
日次のコスト概要
AGENT_ID="<agentId>"
SESSION_DIR="${OPENCLAW_STATE_DIR:-$HOME/.openclaw}/agents/$AGENT_ID/sessions"
for f in "$SESSION_DIR"/*.jsonl; do
  date=$(head -1 "$f" | jq -r '.timestamp' | cut -dT -f1)
  cost=$(jq -s '[.[] | .message.usage.cost.total // 0] | add' "$f")
  echo "$date $cost"
done | awk '{a[$1]+=$2} END {for(d in a) print d, "$"a[d]}' | sort -r
セッション内のメッセージ数とトークン数をカウントする
jq -s '{
  messages: length,
  user: [.[] | select(.message.role == "user")] | length,
  assistant: [.[] | select(.message.role == "assistant")] | length,
  first: .[0].timestamp,
  last: .[-1].timestamp
}' <session>.jsonl
ツール使用の内訳
jq -r '.message.content[]? | select(.type == "toolCall") | .name' <session>.jsonl | sort | uniq -c | sort -rn
すべてのセッションを横断してフレーズを検索する
AGENT_ID="<agentId>"
SESSION_DIR="${OPENCLAW_STATE_DIR:-$HOME/.openclaw}/agents/$AGENT_ID/sessions"

# Active sessions only:
rg -l "phrase" "$SESSION_DIR"/*.jsonl

# Active + archived (`.reset.*`, `.deleted.*`) — use this when checking for
# content that may have been compacted/reset/deleted:
rg -l "phrase" "$SESSION_DIR"/*.jsonl \
               "$SESSION_DIR"/*.jsonl.reset.*Z \
               "$SESSION_DIR"/*.jsonl.deleted.*Z 2>/dev/null

ヒント

  • セッションは追記専用の JSONL です(1 行につき 1 つの JSON オブジェクト)
  • 大きなセッションは数 MB になることがあります - サンプリングには head/tail を使用してください
  • sessions.json インデックスはチャットプロバイダー(discord、whatsapp など)をセッション ID にマッピングします
  • リセット/圧縮されたセッションには .jsonl.reset.<timestamp>Z サフィックスが付きます - 依然として 完全な会話記録を含み、検索可能です。
  • 削除されたセッションには .jsonl.deleted.<timestamp>Z サフィックスが付きます - これらも依然として検索可能です。
  • 単純な *.jsonl glob は両方のアーカイブ形式を 見逃します。完全な履歴が必要な場合は、 それらを明示的に含めてください(上記の「アーカイブされた会話記録を含める」スニペットを参照)。

高速なテキストのみのヒント(低ノイズ)

AGENT_ID="<agentId>"
SESSION_DIR="${OPENCLAW_STATE_DIR:-$HOME/.openclaw}/agents/$AGENT_ID/sessions"
jq -r 'select(.type=="message") | .message.content[]? | select(.type=="text") | .text' "$SESSION_DIR"/<id>.jsonl | rg 'keyword'

コメント