Class: Chocomint::Logger::SqliteLogger

Inherits:
Object
  • Object
show all
Defined in:
lib/chocomint/logger/sqlite_logger.rb

Overview

全試行を SQLite に記録する (DESIGN §12)。

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ SqliteLogger



12
13
14
15
16
# File 'lib/chocomint/logger/sqlite_logger.rb', line 12

def initialize(path)
  FileUtils.mkdir_p(File.dirname(path)) unless File.dirname(path).empty?
  @db = SQLite3::Database.new(path)
  create_schema
end

Instance Method Details

#closeObject



185
# File 'lib/chocomint/logger/sqlite_logger.rb', line 185

def close = @db.close

#count(trace_id: nil) ⇒ Object

ページネーション用の総件数。trace_id 指定時はその trace の件数。



176
177
178
179
180
181
182
183
# File 'lib/chocomint/logger/sqlite_logger.rb', line 176

def count(trace_id: nil)
  trace_id = normalize_text(trace_id)
  if trace_id
    @db.execute("SELECT COUNT(*) FROM executions WHERE trace_id = ?", [trace_id])
  else
    @db.execute("SELECT COUNT(*) FROM executions")
  end.first.first
end

#execution(id) ⇒ Object

監査ログ 1 件を id 指定で取得する。無ければ nil。



161
162
163
164
165
166
167
168
169
170
171
172
173
# File 'lib/chocomint/logger/sqlite_logger.rb', line 161

def execution(id)
  @db.results_as_hash = true
  @db.execute(
    "      SELECT id, trace_id, attempt, request, proposal, result,\n             verifier_output, status, created_at\n      FROM executions WHERE id = ?\n    SQL\n    [id]\n  ).first\nensure\n  @db.results_as_hash = false\nend\n",

#llm_payload(id) ⇒ Object

LLM ペイロード 1 件を id 指定で取得する。無ければ nil。



113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/chocomint/logger/sqlite_logger.rb', line 113

def llm_payload(id)
  @db.results_as_hash = true
  @db.execute(
    "      SELECT id, trace_id, role, model, request_body, request_headers,\n             response_status, response_body, created_at\n      FROM llm_payloads WHERE id = ?\n    SQL\n    [id]\n  ).first\nensure\n  @db.results_as_hash = false\nend\n",

#llm_payload_count(trace_id: nil) ⇒ Object

LLM ペイロードの総件数。trace_id 指定時はその trace の件数。



128
129
130
131
132
133
134
135
# File 'lib/chocomint/logger/sqlite_logger.rb', line 128

def llm_payload_count(trace_id: nil)
  trace_id = normalize_text(trace_id)
  if trace_id
    @db.execute("SELECT COUNT(*) FROM llm_payloads WHERE trace_id = ?", [trace_id])
  else
    @db.execute("SELECT COUNT(*) FROM llm_payloads")
  end.first.first
end

#recent(limit: 100, offset: 0, trace_id: nil) ⇒ Object

監査ログを新しい順に取得する。ブラウザ表示 (GET /logs) 用。 trace_id を指定するとその trace のみに絞る。offset でページ送り。 返り値は各行を Hash(カラム名 => 値) にした配列。



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/chocomint/logger/sqlite_logger.rb', line 140

def recent(limit: 100, offset: 0, trace_id: nil)
  trace_id = normalize_text(trace_id)
  where = trace_id ? "WHERE trace_id = ?" : ""
  params = trace_id ? [trace_id, limit, offset] : [limit, offset]
  @db.results_as_hash = true
  @db.execute(
    "      SELECT id, trace_id, attempt, request, proposal, result,\n             verifier_output, status, created_at\n      FROM executions\n      \#{where}\n      ORDER BY id DESC\n      LIMIT ? OFFSET ?\n    SQL\n    params\n  )\nensure\n  @db.results_as_hash = false\nend\n",

#recent_llm_payloads(limit: 100, offset: 0, trace_id: nil) ⇒ Object

LLM 送信ペイロードを新しい順に取得する。trace_id で絞り込み可能。



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/chocomint/logger/sqlite_logger.rb', line 73

def recent_llm_payloads(limit: 100, offset: 0, trace_id: nil)
  trace_id = normalize_text(trace_id)
  where = trace_id ? "WHERE trace_id = ?" : ""
  params = trace_id ? [trace_id, limit, offset] : [limit, offset]
  @db.results_as_hash = true
  @db.execute(
    "      SELECT id, trace_id, role, model, request_body, request_headers,\n             response_status, response_body, created_at\n      FROM llm_payloads\n      \#{where}\n      ORDER BY id DESC\n      LIMIT ? OFFSET ?\n    SQL\n    params\n  )\nensure\n  @db.results_as_hash = false\nend\n",

#record(trace_id:, attempt:, request:, proposal:, result:, status:, verifier_output: nil) ⇒ Object

1 attempt を 1 行として保存する。



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/chocomint/logger/sqlite_logger.rb', line 19

def record(trace_id:, attempt:, request:, proposal:, result:, status:, verifier_output: nil)
  @db.execute(
    "      INSERT INTO executions\n        (trace_id, attempt, request, proposal, result, verifier_output, status, created_at)\n      VALUES (?, ?, ?, ?, ?, ?, ?, ?)\n    SQL\n    [\n      trace_id,\n      attempt,\n      request.to_s,\n      serialize(proposal),\n      serialize(result),\n      verifier_output,\n      status,\n      Time.now.utc.iso8601\n    ]\n  )\nend\n",

#record_llm_payload(role:, model:, request_body:, request_headers:, trace_id: nil) ⇒ Object

LLM への送信内容 (ヘッダ含む生ボディ全体) を 1 呼び出し 1 行で記録する。 role: "primary" / "verifier"。body/headers は Hash を渡すと JSON 化する。 戻り値: 挿入した行の id (後で update_llm_payload_response に渡す)。



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/chocomint/logger/sqlite_logger.rb', line 42

def record_llm_payload(role:, model:, request_body:, request_headers:, trace_id: nil)
  @db.execute(
    "      INSERT INTO llm_payloads\n        (trace_id, role, model, request_body, request_headers, created_at)\n      VALUES (?, ?, ?, ?, ?, ?)\n    SQL\n    [\n      trace_id,\n      role.to_s,\n      model.to_s,\n      serialize(request_body),\n      serialize(request_headers),\n      Time.now.utc.iso8601\n    ]\n  )\n  @db.last_insert_row_id\nend\n",

#tool_outcomes(trace_id) ⇒ Object

trace_id に紐づくツール実行の正常性判定 (status / verifier_output) を attempt 昇順で返す。LLM ペイロード詳細で「判定結果」を併記するため。



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/chocomint/logger/sqlite_logger.rb', line 95

def tool_outcomes(trace_id)
  trace_id = normalize_text(trace_id)
  return [] if trace_id.nil?

  @db.results_as_hash = true
  @db.execute(
    "      SELECT attempt, status, verifier_output, proposal\n      FROM executions WHERE trace_id = ?\n      ORDER BY attempt ASC, id ASC\n    SQL\n    [trace_id]\n  )\nensure\n  @db.results_as_hash = false\nend\n",

#update_llm_payload_response(id, response_status:, response_body:) ⇒ Object

記録済みペイロード行に LLM レスポンス (HTTP ステータス + 生ボディ) を追記する。 id は record_llm_payload の戻り値。body は文字列/Hash どちらも可。



63
64
65
66
67
68
69
70
# File 'lib/chocomint/logger/sqlite_logger.rb', line 63

def update_llm_payload_response(id, response_status:, response_body:)
  return if id.nil?

  @db.execute(
    "UPDATE llm_payloads SET response_status = ?, response_body = ? WHERE id = ?",
    [response_status, serialize(response_body), id]
  )
end