legion-data 1.10.1 → 1.10.2

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: ec6d2ef95eb45caa64e713c5dc236752a856cb7298e6b054099587b4faedcda1
4
- data.tar.gz: 7df69945231cc4e38501cd1e49149ea44110db060600ea6606fb11008c5d1df6
3
+ metadata.gz: 212e01a164b58ab2a8a4273497e98acf0d99f174f4a66a77c7c707899685f2ed
4
+ data.tar.gz: e3302347dd4f8d3ce634fc88110a645ad6986aa5d8b531d5a9187fe894872ae0
5
5
  SHA512:
6
- metadata.gz: 3bd4a9fc8ed37d9fcbf92796baab4891601dbbed4b75a4bc1f752ee164a437af5a6e22516796977051c67c1bf555145fab2d2043a8754c7f7bf86175ebc977df
7
- data.tar.gz: 3af41e387d8b98a3c7a8b527b88c6824b022d3baacc27c7243b5bafb7e7dc8c7e2876edc71e66994456667ade8a9b4b8854f55b1cffcfd1630ac082ffd87cdb0
6
+ metadata.gz: 6399d19fe35c9b3e975522d6d2b4654d0bc56240e508a38bcf55c4cb064fbb1214f7e2c5de7f3c4828a79f8543044da476811808d574b020609ab20adcc8d778
7
+ data.tar.gz: 87e1b1e58c66e464cbb1ccf41ad2a1917531edff611dcef0fc0f6b20f7dfe9331f854e684c00ace11557c714cd77e6131cd2a6b07c837f60d670c0d9fdf9b704
data/CHANGELOG.md CHANGED
@@ -1,11 +1,25 @@
1
1
  # Legion::Data Changelog
2
2
 
3
+ ## [1.10.2] - 2026-06-02
4
+
5
+ ### Fixed
6
+ - Replace `return` with `next` in migration blocks — Sequel uses `instance_exec`, bare `return` raises `LocalJumpError` (migrations 019, 044, 045, 046, 118, 120)
7
+ - Make migrations 118-130 idempotent with schema column checks for safe re-run after partial failures
8
+ - Restore migration 131 (`add_column :schema_version` to `llm_tool_calls`) with idempotent guard — preserves contiguous migration sequence for existing installations
9
+
10
+ ### Added
11
+ - Migration 132: drops unused `schema_version` column from `llm_tool_calls` (no code reads/writes it)
12
+ - Migration 133: allows NULL on `context_tokens` in `llm_message_inference_requests` — prevents NOT NULL violations when token counts are unavailable
13
+
3
14
  ## [1.10.1] - 2026-06-01
4
15
 
5
16
  ### Added
6
17
 
7
- - Migration 130: adds `pii_types_json` (TEXT), `jurisdictions_json` (TEXT), and `schema_version` (Integer, default 15) to `llm_conversations`. Required by lex-llm-ledger OfficialRecordWriter for compliance metadata.
8
- - Migration 131: adds `schema_version` (Integer, default 15) to `llm_tool_calls`. Required by lex-llm-ledger OfficialRecordWriter.
18
+ - Migration 130: adds `pii_types_json` (TEXT) and `jurisdictions_json` (TEXT) to `llm_conversations`. Required by lex-llm-ledger OfficialRecordWriter for compliance metadata.
19
+
20
+ ### Removed
21
+
22
+ - `schema_version` column removed from lex-llm-ledger writer — no longer written to any table. Column remains on `llm_skill_events` (migration 129) but is not actively populated.
9
23
 
10
24
  ## [1.10.0] - 2026-06-01
11
25
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Sequel.migration do
4
4
  up do
5
- return unless table_exists?(:audit_log)
5
+ next unless table_exists?(:audit_log)
6
6
 
7
7
  cols = schema(:audit_log).map(&:first)
8
8
  idxs = indexes(:audit_log)
@@ -33,7 +33,7 @@ Sequel.migration do
33
33
  end
34
34
 
35
35
  down do
36
- return unless table_exists?(:audit_log)
36
+ next unless table_exists?(:audit_log)
37
37
 
38
38
  cols = schema(:audit_log).map(&:first)
39
39
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Sequel.migration do
4
4
  up do
5
- return unless table_exists?(:memory_traces)
5
+ next unless table_exists?(:memory_traces)
6
6
 
7
7
  existing = schema(:memory_traces).map(&:first)
8
8
 
@@ -45,7 +45,7 @@ Sequel.migration do
45
45
  end
46
46
 
47
47
  down do
48
- return unless table_exists?(:memory_traces)
48
+ next unless table_exists?(:memory_traces)
49
49
 
50
50
  existing = schema(:memory_traces).map(&:first)
51
51
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Sequel.migration do
4
4
  up do
5
- return if table_exists?(:memory_associations)
5
+ next if table_exists?(:memory_associations)
6
6
 
7
7
  create_table(:memory_associations) do
8
8
  primary_key :id
@@ -2,7 +2,7 @@
2
2
 
3
3
  Sequel.migration do
4
4
  up do
5
- return if table_exists?(:metering_hourly_rollup)
5
+ next if table_exists?(:metering_hourly_rollup)
6
6
 
7
7
  create_table(:metering_hourly_rollup) do
8
8
  primary_key :id
@@ -7,10 +7,10 @@
7
7
 
8
8
  Sequel.migration do
9
9
  up do
10
- return unless table_exists?(:audit_records)
10
+ next unless table_exists?(:audit_records)
11
11
 
12
12
  existing = schema(:audit_records).map(&:first)
13
- return if existing.include?(:entity_type)
13
+ next if existing.include?(:entity_type)
14
14
 
15
15
  alter_table(:audit_records) do
16
16
  add_column :entity_type, String, size: 100, null: true
@@ -20,7 +20,7 @@ Sequel.migration do
20
20
  end
21
21
 
22
22
  down do
23
- return unless table_exists?(:audit_records)
23
+ next unless table_exists?(:audit_records)
24
24
 
25
25
  alter_table(:audit_records) do
26
26
  drop_column :entity_type if schema(:audit_records).any? { |col, _| col == :entity_type }
@@ -14,7 +14,7 @@
14
14
 
15
15
  Sequel.migration do
16
16
  up do
17
- return unless table_exists?(:apollo_entries)
17
+ next unless table_exists?(:apollo_entries)
18
18
 
19
19
  run 'CREATE INDEX IF NOT EXISTS idx_apollo_submitted_by ON apollo_entries (submitted_by)'
20
20
  run 'CREATE INDEX IF NOT EXISTS idx_apollo_submitted_from ON apollo_entries (submitted_from)'
@@ -29,26 +29,26 @@ Sequel.migration do
29
29
  run "CREATE INDEX IF NOT EXISTS idx_apollo_decay_target ON apollo_entries (updated_at) WHERE status != 'archived'"
30
30
  run "CREATE INDEX IF NOT EXISTS idx_apollo_candidates ON apollo_entries (status, source_provider, source_channel) WHERE status = 'candidate'"
31
31
 
32
- return unless table_exists?(:apollo_entries_archive)
32
+ next unless table_exists?(:apollo_entries_archive)
33
33
 
34
34
  run 'CREATE INDEX IF NOT EXISTS idx_archive_content_hash ON apollo_entries_archive (content_hash)'
35
35
  run 'CREATE INDEX IF NOT EXISTS idx_archive_source_agent ON apollo_entries_archive (source_agent)'
36
36
  run 'CREATE INDEX IF NOT EXISTS idx_archive_archived_at ON apollo_entries_archive (archived_at)'
37
37
 
38
- return unless table_exists?(:apollo_relations)
38
+ next unless table_exists?(:apollo_relations)
39
39
 
40
40
  run 'CREATE INDEX IF NOT EXISTS idx_apollo_rel_from ON apollo_relations (from_entry_id)'
41
41
  run 'CREATE INDEX IF NOT EXISTS idx_apollo_rel_to ON apollo_relations (to_entry_id)'
42
42
  run 'CREATE INDEX IF NOT EXISTS idx_apollo_rel_type ON apollo_relations (relation_type)'
43
43
  run 'CREATE INDEX IF NOT EXISTS idx_apollo_rel_composite ON apollo_relations (from_entry_id, relation_type)'
44
44
 
45
- return unless table_exists?(:apollo_expertise)
45
+ next unless table_exists?(:apollo_expertise)
46
46
 
47
47
  run 'CREATE INDEX IF NOT EXISTS idx_apollo_exp_agent ON apollo_expertise (agent_id)'
48
48
  run 'CREATE INDEX IF NOT EXISTS idx_apollo_exp_domain ON apollo_expertise (domain)'
49
49
  run 'CREATE INDEX IF NOT EXISTS idx_apollo_exp_composite ON apollo_expertise (agent_id, domain)'
50
50
 
51
- return unless table_exists?(:apollo_operations)
51
+ next unless table_exists?(:apollo_operations)
52
52
 
53
53
  run 'CREATE INDEX IF NOT EXISTS idx_apollo_ops_created ON apollo_operations (created_at)'
54
54
  run 'CREATE INDEX IF NOT EXISTS idx_apollo_ops_operation ON apollo_operations (operation)'
@@ -1,20 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Add cached_input_tokens and cache_creation_tokens to llm_message_inference_metrics.
4
- # Tracks cache hit tokens (read from cache) and cache write tokens separately from
5
- # standard input/output token counts.
6
- #
7
- # See: https://github.com/LegionIO/legion-data/issues/55
8
-
9
3
  Sequel.migration do
10
4
  up do
5
+ next unless table_exists?(:llm_message_inference_metrics)
6
+
7
+ existing = schema(:llm_message_inference_metrics).map(&:first)
8
+
11
9
  alter_table(:llm_message_inference_metrics) do
12
- add_column :cached_input_tokens, Integer, null: false, default: 0
13
- add_column :cache_creation_tokens, Integer, null: false, default: 0
10
+ add_column :cached_input_tokens, Integer, null: false, default: 0 unless existing.include?(:cached_input_tokens)
11
+ add_column :cache_creation_tokens, Integer, null: false, default: 0 unless existing.include?(:cache_creation_tokens)
14
12
  end
15
13
  end
16
14
 
17
15
  down do
16
+ next unless table_exists?(:llm_message_inference_metrics)
17
+
18
18
  alter_table(:llm_message_inference_metrics) do
19
19
  drop_column :cache_creation_tokens
20
20
  drop_column :cached_input_tokens
@@ -1,17 +1,35 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Sequel.migration do
4
- change do
4
+ up do
5
+ next unless table_exists?(:llm_tool_calls)
6
+
7
+ existing = schema(:llm_tool_calls).map(&:first)
8
+
9
+ alter_table(:llm_tool_calls) do
10
+ add_column :tool_arguments_json, :text, null: true unless existing.include?(:tool_arguments_json)
11
+ add_column :tool_result_json, :text, null: true unless existing.include?(:tool_result_json)
12
+ add_column :tool_category, String, size: 64, null: true unless existing.include?(:tool_category)
13
+ add_column :data_handling_classification, String, size: 32, null: true unless existing.include?(:data_handling_classification)
14
+ add_column :policy_decision, String, size: 32, null: true unless existing.include?(:policy_decision)
15
+ add_column :requires_human_approval, TrueClass, null: true unless existing.include?(:requires_human_approval)
16
+ end
17
+
18
+ add_index :llm_tool_calls, :tool_category, name: :idx_tool_calls_tool_category, if_not_exists: true
19
+ add_index :llm_tool_calls, :data_handling_classification, name: :idx_tool_calls_data_handling_classification, if_not_exists: true
20
+ add_index :llm_tool_calls, :policy_decision, name: :idx_tool_calls_policy_decision, if_not_exists: true
21
+ end
22
+
23
+ down do
24
+ next unless table_exists?(:llm_tool_calls)
25
+
5
26
  alter_table(:llm_tool_calls) do
6
- add_column :tool_arguments_json, :text, null: true
7
- add_column :tool_result_json, :text, null: true
8
- add_column :tool_category, String, size: 64, null: true
9
- add_column :data_handling_classification, String, size: 32, null: true
10
- add_column :policy_decision, String, size: 32, null: true
11
- add_column :requires_human_approval, TrueClass, null: true
12
- add_index :tool_category, name: :idx_tool_calls_tool_category
13
- add_index :data_handling_classification, name: :idx_tool_calls_data_handling_classification
14
- add_index :policy_decision, name: :idx_tool_calls_policy_decision
27
+ drop_column :requires_human_approval
28
+ drop_column :policy_decision
29
+ drop_column :data_handling_classification
30
+ drop_column :tool_category
31
+ drop_column :tool_result_json
32
+ drop_column :tool_arguments_json
15
33
  end
16
34
  end
17
35
  end
@@ -1,11 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Sequel.migration do
4
- change do
4
+ up do
5
+ next unless table_exists?(:llm_tool_call_attempts)
6
+
7
+ existing = schema(:llm_tool_call_attempts).map(&:first)
8
+
9
+ alter_table(:llm_tool_call_attempts) do
10
+ add_column :attempt_input_json, :text, null: true unless existing.include?(:attempt_input_json)
11
+ add_column :attempt_output_json, :text, null: true unless existing.include?(:attempt_output_json)
12
+ add_column :error_details_json, :text, null: true unless existing.include?(:error_details_json)
13
+ end
14
+ end
15
+
16
+ down do
17
+ next unless table_exists?(:llm_tool_call_attempts)
18
+
5
19
  alter_table(:llm_tool_call_attempts) do
6
- add_column :attempt_input_json, :text, null: true
7
- add_column :attempt_output_json, :text, null: true
8
- add_column :error_details_json, :text, null: true
20
+ drop_column :error_details_json
21
+ drop_column :attempt_output_json
22
+ drop_column :attempt_input_json
9
23
  end
10
24
  end
11
25
  end
@@ -1,13 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # NOTE: response_content_hash already exists (migration 080) — skipped.
4
-
5
3
  Sequel.migration do
6
- change do
4
+ up do
5
+ next unless table_exists?(:llm_message_inference_responses)
6
+
7
+ existing = schema(:llm_message_inference_responses).map(&:first)
8
+
9
+ alter_table(:llm_message_inference_responses) do
10
+ add_column :route_attempts, Integer, null: true, default: 0 unless existing.include?(:route_attempts)
11
+ add_column :escalation_chain_ref, String, size: 128, null: true unless existing.include?(:escalation_chain_ref)
12
+ end
13
+
14
+ add_index :llm_message_inference_responses, :escalation_chain_ref,
15
+ name: :idx_inference_responses_escalation_chain_ref, if_not_exists: true
16
+ end
17
+
18
+ down do
19
+ next unless table_exists?(:llm_message_inference_responses)
20
+
7
21
  alter_table(:llm_message_inference_responses) do
8
- add_column :route_attempts, Integer, null: true, default: 0
9
- add_column :escalation_chain_ref, String, size: 128, null: true
10
- add_index :escalation_chain_ref, name: :idx_inference_responses_escalation_chain_ref
22
+ drop_column :escalation_chain_ref
23
+ drop_column :route_attempts
11
24
  end
12
25
  end
13
26
  end
@@ -1,12 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # NOTE: request_content_hash, curation_strategy, and tool_policy already exist
4
- # (migration 079) — all skipped. Only parent_request_id is new.
5
-
6
3
  Sequel.migration do
7
- change do
4
+ up do
5
+ next unless table_exists?(:llm_message_inference_requests)
6
+
7
+ existing = schema(:llm_message_inference_requests).map(&:first)
8
+ next if existing.include?(:parent_request_id)
9
+
8
10
  alter_table(:llm_message_inference_requests) do
9
11
  add_foreign_key :parent_request_id, :llm_message_inference_requests, null: true, on_delete: :set_null
10
12
  end
11
13
  end
14
+
15
+ down do
16
+ next unless table_exists?(:llm_message_inference_requests)
17
+
18
+ alter_table(:llm_message_inference_requests) do
19
+ drop_foreign_key :parent_request_id
20
+ end
21
+ end
12
22
  end
@@ -2,6 +2,8 @@
2
2
 
3
3
  Sequel.migration do
4
4
  up do
5
+ next if table_exists?(:llm_skill_events)
6
+
5
7
  create_table(:llm_skill_events) do
6
8
  primary_key :id
7
9
 
@@ -23,6 +25,6 @@ Sequel.migration do
23
25
  end
24
26
 
25
27
  down do
26
- drop_table :llm_skill_events
28
+ drop_table(:llm_skill_events) if table_exists?(:llm_skill_events)
27
29
  end
28
30
  end
@@ -2,16 +2,20 @@
2
2
 
3
3
  Sequel.migration do
4
4
  up do
5
+ next unless table_exists?(:llm_conversations)
6
+
7
+ existing = schema(:llm_conversations).map(&:first)
8
+
5
9
  alter_table(:llm_conversations) do
6
- add_column :pii_types_json, :text, null: true
7
- add_column :jurisdictions_json, :text, null: true
8
- add_column :schema_version, Integer, null: false, default: 15
10
+ add_column :pii_types_json, :text, null: true unless existing.include?(:pii_types_json)
11
+ add_column :jurisdictions_json, :text, null: true unless existing.include?(:jurisdictions_json)
9
12
  end
10
13
  end
11
14
 
12
15
  down do
16
+ next unless table_exists?(:llm_conversations)
17
+
13
18
  alter_table(:llm_conversations) do
14
- drop_column :schema_version
15
19
  drop_column :jurisdictions_json
16
20
  drop_column :pii_types_json
17
21
  end
@@ -2,6 +2,9 @@
2
2
 
3
3
  Sequel.migration do
4
4
  up do
5
+ existing = schema(:llm_tool_calls).map(&:first)
6
+ next if existing.include?(:schema_version)
7
+
5
8
  alter_table(:llm_tool_calls) do
6
9
  add_column :schema_version, Integer, null: false, default: 15
7
10
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ Sequel.migration do
4
+ up do
5
+ existing = schema(:llm_tool_calls).map(&:first)
6
+ next unless existing.include?(:schema_version)
7
+
8
+ alter_table(:llm_tool_calls) do
9
+ drop_column :schema_version
10
+ end
11
+ end
12
+
13
+ down do
14
+ alter_table(:llm_tool_calls) do
15
+ add_column :schema_version, Integer, null: false, default: 15
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ Sequel.migration do
4
+ up do
5
+ alter_table(:llm_message_inference_requests) do
6
+ set_column_allow_null :context_tokens
7
+ end
8
+ end
9
+
10
+ down do
11
+ alter_table(:llm_message_inference_requests) do
12
+ set_column_not_null :context_tokens
13
+ end
14
+ end
15
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Legion
4
4
  module Data
5
- VERSION = '1.10.1'
5
+ VERSION = '1.10.2'
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.1
4
+ version: 1.10.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity
@@ -278,6 +278,8 @@ files:
278
278
  - lib/legion/data/migrations/129_create_llm_skill_events.rb
279
279
  - lib/legion/data/migrations/130_add_llm_conversations_compliance_columns.rb
280
280
  - lib/legion/data/migrations/131_add_llm_tool_calls_schema_version.rb
281
+ - lib/legion/data/migrations/132_drop_schema_version_from_llm_tool_calls.rb
282
+ - lib/legion/data/migrations/133_allow_null_context_tokens.rb
281
283
  - lib/legion/data/model.rb
282
284
  - lib/legion/data/models/apollo/access_log.rb
283
285
  - lib/legion/data/models/apollo/entries.rb