legion-data 1.10.2 → 1.10.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 212e01a164b58ab2a8a4273497e98acf0d99f174f4a66a77c7c707899685f2ed
4
- data.tar.gz: e3302347dd4f8d3ce634fc88110a645ad6986aa5d8b531d5a9187fe894872ae0
3
+ metadata.gz: 7f3b320363f209f8dfae3ad1a9757bae5e17dd4d7e6327b849b0d8804df22c07
4
+ data.tar.gz: ac12848278ac407233eb43b6f5a72dbf503b030a9d404e88578fdb8ebd173cc5
5
5
  SHA512:
6
- metadata.gz: 6399d19fe35c9b3e975522d6d2b4654d0bc56240e508a38bcf55c4cb064fbb1214f7e2c5de7f3c4828a79f8543044da476811808d574b020609ab20adcc8d778
7
- data.tar.gz: 87e1b1e58c66e464cbb1ccf41ad2a1917531edff611dcef0fc0f6b20f7dfe9331f854e684c00ace11557c714cd77e6131cd2a6b07c837f60d670c0d9fdf9b704
6
+ metadata.gz: 0e0331f06f446400f70581981a8f083e1baac336aee984904f56af60eb9a9d021d56af48c8b845a13beaebd4aca1ba0e7a264af1101f78426d447a4cfd3d86b2
7
+ data.tar.gz: 70b599bee80873cd661bdd09aacb406da9d8cdd479d270b6012032945aedb08bb82a3819f00f11f44e45b3470b8b88042491e5e892900564d334d6b4748f945a
data/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Legion::Data Changelog
2
2
 
3
+ ## [1.10.5] - 2026-06-16
4
+
5
+ ### Added
6
+ - Migration 135: adds context token accounting columns to `llm_message_inference_metrics` — `llm_message_inference_metrics` is now the canonical source of truth for all pipeline context token metrics (request messages, loaded/curated/archived history, thinking strip savings, context-window enforcement savings, RAG injection, system/baseline prompt, tool definitions, final context estimate). Includes `context_accounting_status` and `context_accounting_json` for provenance.
7
+ - Migration 135: creates `llm_context_accounting_events` table for drill-down evidence rows (not a second source of token truth — totals reconcile to the canonical metrics row).
8
+ - Model: `Legion::Data::Models::LLM::ContextAccountingEvent` with foreign key associations to request, response, and metric.
9
+ - Association: `MessageInferenceMetric#context_accounting_events`.
10
+
11
+ ## [1.10.4] - 2026-06-12
12
+
13
+ ### Added
14
+ - Migration 134: adds `operation` (String 64), `dispatch_path` (String 32), and `idempotency_key` (String 128) columns to `llm_route_attempts` with indexes on `operation` and `idempotency_key`. Enables per-attempt tracking of the LLM operation type, routing path, and deduplication key.
15
+
16
+ ## [1.10.3] - 2026-06-10
17
+
18
+ ### Changed
19
+ - `connection_validation` now defaults to `false` — the Sequel connection_validator extension issues a `SELECT NULL` on every pool checkout/checkin and before real queries, which measurably degrades throughput; query-time error handling already recovers stale/dead connections. Set `connection_validation: true` in settings to opt back in (timeout semantics unchanged: `-1` validates every checkout)
20
+ - Pool timeout assignments read `connection_validation_timeout` / `connection_expiration_timeout` directly from settings — removed inline `|| 600` / `|| 14_400` shadow defaults that disagreed with the documented settings defaults
21
+
3
22
  ## [1.10.2] - 2026-06-02
4
23
 
5
24
  ### Fixed
@@ -581,12 +581,12 @@ module Legion
581
581
 
582
582
  if data[:connection_validation] != false
583
583
  @sequel.extension(:connection_validator)
584
- @sequel.pool.connection_validation_timeout = data[:connection_validation_timeout] || 600
584
+ @sequel.pool.connection_validation_timeout = data[:connection_validation_timeout]
585
585
  end
586
586
 
587
587
  if data[:connection_expiration] != false
588
588
  @sequel.extension(:connection_expiration)
589
- @sequel.pool.connection_expiration_timeout = data[:connection_expiration_timeout] || 14_400
589
+ @sequel.pool.connection_expiration_timeout = data[:connection_expiration_timeout]
590
590
  end
591
591
  rescue StandardError => e
592
592
  handle_exception(e, level: :warn, handled: true, operation: :configure_extensions, adapter: adapter)
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ Sequel.migration do
4
+ up do
5
+ alter_table(:llm_route_attempts) do
6
+ add_column :operation, String, size: 64, null: true
7
+ add_column :dispatch_path, String, size: 32, null: true
8
+ add_column :idempotency_key, String, size: 128, null: true
9
+ add_index :operation, name: :idx_route_attempts_operation
10
+ add_index :idempotency_key, name: :idx_route_attempts_idempotency_key
11
+ end
12
+ end
13
+
14
+ down do
15
+ alter_table(:llm_route_attempts) do
16
+ drop_index :operation, name: :idx_route_attempts_operation
17
+ drop_index :idempotency_key, name: :idx_route_attempts_idempotency_key
18
+ drop_column :operation
19
+ drop_column :dispatch_path
20
+ drop_column :idempotency_key
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ Sequel.migration do
4
+ up do
5
+ alter_table(:llm_message_inference_metrics) do
6
+ add_column :request_message_estimated_tokens, Integer, null: false, default: 0
7
+ add_column :loaded_history_estimated_tokens, Integer, null: false, default: 0
8
+ add_column :curated_history_estimated_tokens, Integer, null: false, default: 0
9
+ add_column :curation_saved_estimated_tokens, Integer, null: false, default: 0
10
+ add_column :stripped_thinking_estimated_tokens, Integer, null: false, default: 0
11
+ add_column :archived_history_estimated_tokens, Integer, null: false, default: 0
12
+ add_column :archive_saved_estimated_tokens, Integer, null: false, default: 0
13
+ add_column :context_window_saved_estimated_tokens, Integer, null: false, default: 0
14
+ add_column :rag_injected_estimated_tokens, Integer, null: false, default: 0
15
+ add_column :system_prompt_estimated_tokens, Integer, null: false, default: 0
16
+ add_column :baseline_system_estimated_tokens, Integer, null: false, default: 0
17
+ add_column :tool_definition_estimated_tokens, Integer, null: false, default: 0
18
+ add_column :final_context_estimated_tokens, Integer, null: false, default: 0
19
+ add_column :loaded_history_message_count, Integer, null: false, default: 0
20
+ add_column :curated_history_message_count, Integer, null: false, default: 0
21
+ add_column :archived_history_message_count, Integer, null: false, default: 0
22
+ add_column :stripped_thinking_message_count, Integer, null: false, default: 0
23
+ add_column :context_window_message_count_before, Integer, null: false, default: 0
24
+ add_column :context_window_message_count_after, Integer, null: false, default: 0
25
+ add_column :rag_entry_count, Integer, null: false, default: 0
26
+ add_column :tool_definition_count, Integer, null: false, default: 0
27
+ add_column :context_accounting_status, String, size: 64, null: false, default: 'missing'
28
+ add_column :context_accounting_json, String, text: true
29
+ end
30
+
31
+ create_table(:llm_context_accounting_events) do
32
+ primary_key :id
33
+ String :uuid, size: 36, null: false, unique: true
34
+ foreign_key :message_inference_request_id, :llm_message_inference_requests, null: false, on_delete: :cascade
35
+ foreign_key :message_inference_response_id, :llm_message_inference_responses, null: true, on_delete: :set_null
36
+ foreign_key :message_inference_metric_id, :llm_message_inference_metrics, null: true, on_delete: :set_null
37
+ String :conversation_ref, size: 128
38
+ String :request_ref, size: 128, null: false
39
+ String :event_type, size: 64, null: false
40
+ String :component, size: 64, null: false
41
+ Integer :estimated_tokens_before, null: false, default: 0
42
+ Integer :estimated_tokens_after, null: false, default: 0
43
+ Integer :estimated_tokens_delta, null: false, default: 0
44
+ Integer :message_count_before, null: false, default: 0
45
+ Integer :message_count_after, null: false, default: 0
46
+ String :metadata_json, text: true
47
+ DateTime :recorded_at
48
+ DateTime :inserted_at, null: false, default: Sequel::CURRENT_TIMESTAMP
49
+
50
+ index :message_inference_request_id
51
+ index :message_inference_response_id
52
+ index :message_inference_metric_id
53
+ index :request_ref
54
+ index :conversation_ref
55
+ index %i[event_type component]
56
+ index :recorded_at
57
+ end
58
+ end
59
+
60
+ down do
61
+ drop_table(:llm_context_accounting_events)
62
+
63
+ alter_table(:llm_message_inference_metrics) do
64
+ drop_column :context_accounting_json
65
+ drop_column :context_accounting_status
66
+ drop_column :tool_definition_count
67
+ drop_column :rag_entry_count
68
+ drop_column :context_window_message_count_after
69
+ drop_column :context_window_message_count_before
70
+ drop_column :stripped_thinking_message_count
71
+ drop_column :archived_history_message_count
72
+ drop_column :curated_history_message_count
73
+ drop_column :loaded_history_message_count
74
+ drop_column :final_context_estimated_tokens
75
+ drop_column :tool_definition_estimated_tokens
76
+ drop_column :baseline_system_estimated_tokens
77
+ drop_column :system_prompt_estimated_tokens
78
+ drop_column :rag_injected_estimated_tokens
79
+ drop_column :context_window_saved_estimated_tokens
80
+ drop_column :archive_saved_estimated_tokens
81
+ drop_column :archived_history_estimated_tokens
82
+ drop_column :stripped_thinking_estimated_tokens
83
+ drop_column :curation_saved_estimated_tokens
84
+ drop_column :curated_history_estimated_tokens
85
+ drop_column :loaded_history_estimated_tokens
86
+ drop_column :request_message_estimated_tokens
87
+ end
88
+ end
89
+ end
@@ -21,7 +21,8 @@ module Legion
21
21
  rbac/role_assignments rbac/runner_grants rbac/cross_team_grants
22
22
  llm/conversation llm/message llm/message_inference_request
23
23
  llm/message_inference_response llm/route_attempt
24
- llm/message_inference_metric llm/tool_call llm/tool_call_attempt
24
+ llm/message_inference_metric llm/context_accounting_event
25
+ llm/tool_call llm/tool_call_attempt
25
26
  llm/conversation_compaction llm/policy_evaluation
26
27
  llm/security_event llm/registry_event]
27
28
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'model_helpers'
4
+
5
+ module Legion
6
+ module Data
7
+ module Models
8
+ module LLM
9
+ class ContextAccountingEvent < Sequel::Model(:llm_context_accounting_events)
10
+ include ModelHelpers
11
+
12
+ many_to_one :message_inference_request
13
+ many_to_one :message_inference_response
14
+ many_to_one :message_inference_metric
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -11,6 +11,7 @@ module Legion
11
11
 
12
12
  many_to_one :message_inference_request
13
13
  many_to_one :message_inference_response
14
+ one_to_many :context_accounting_events
14
15
 
15
16
  class << self
16
17
  def finance_usage_by_cost_center_model_day(cost_center: nil, model_key: nil, from: nil, to: nil)
@@ -48,8 +48,12 @@ module Legion
48
48
  sql_log_level: 'debug',
49
49
 
50
50
  # Connection health (network adapters only, ignored for sqlite)
51
- # -1 means validate on every checkout, catching stale connections from VPN/sleep/network changes immediately
52
- connection_validation: true,
51
+ # Validation is disabled by default: the connection_validator extension issues a
52
+ # SELECT NULL on every checkout/checkin and before real queries, which kills
53
+ # throughput. Connection errors are already rescued and reconnected at query time.
54
+ # When enabled, connection_validation_timeout: -1 validates on every checkout
55
+ # (catches stale connections from VPN/sleep/network changes immediately).
56
+ connection_validation: false,
53
57
  connection_validation_timeout: -1,
54
58
  connection_expiration: true,
55
59
  connection_expiration_timeout: 14_400,
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Legion
4
4
  module Data
5
- VERSION = '1.10.2'
5
+ VERSION = '1.10.5'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: legion-data
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.10.2
4
+ version: 1.10.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity
@@ -280,6 +280,8 @@ files:
280
280
  - lib/legion/data/migrations/131_add_llm_tool_calls_schema_version.rb
281
281
  - lib/legion/data/migrations/132_drop_schema_version_from_llm_tool_calls.rb
282
282
  - lib/legion/data/migrations/133_allow_null_context_tokens.rb
283
+ - lib/legion/data/migrations/134_add_route_attempt_columns.rb
284
+ - lib/legion/data/migrations/135_add_llm_context_token_accounting.rb
283
285
  - lib/legion/data/model.rb
284
286
  - lib/legion/data/models/apollo/access_log.rb
285
287
  - lib/legion/data/models/apollo/entries.rb
@@ -305,6 +307,7 @@ files:
305
307
  - lib/legion/data/models/identity/model_helpers.rb
306
308
  - lib/legion/data/models/identity/principal.rb
307
309
  - lib/legion/data/models/identity/providers.rb
310
+ - lib/legion/data/models/llm/context_accounting_event.rb
308
311
  - lib/legion/data/models/llm/conversation.rb
309
312
  - lib/legion/data/models/llm/conversation_compaction.rb
310
313
  - lib/legion/data/models/llm/message.rb