lex-telemetry 0.1.6 → 0.1.7
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 +4 -4
- data/.github/workflows/ci.yml +4 -4
- data/.rubocop.yml +9 -58
- data/CHANGELOG.md +5 -0
- data/Gemfile +1 -0
- data/lib/legion/extensions/telemetry/parsers/claude_code.rb +32 -32
- data/lib/legion/extensions/telemetry/runners/telemetry.rb +4 -4
- data/lib/legion/extensions/telemetry/version.rb +1 -1
- data/lib/legion/extensions/telemetry.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f37c3484695b8612aec589a24b49f98f8c1be3b0d2892a6e023b27447acd84e1
|
|
4
|
+
data.tar.gz: be1205311b7ee81cf281c3abe03b3f74844dd839bd41a6c9a934a2a7a3ef4b28
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b36a9fdd1e12e9d7fbe4bcde51bdd26ac6eb7fd1aea412f0522b8f31a8739b6e428c869193ea3b8776a7f62df5b7a51c81f05ba4d32397ff406cf5a8788d3fab
|
|
7
|
+
data.tar.gz: 90bcf6ca1386b77a474f0c3becb12327e850380dc6e67513ad1f6871d9e6f058f10c4c3d5b5c7a689bbf70b2b2848288172b5fab0555a946a97f5a025a783870
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -10,8 +10,8 @@ jobs:
|
|
|
10
10
|
ci:
|
|
11
11
|
uses: LegionIO/.github/.github/workflows/ci.yml@main
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
uses: LegionIO/.github/.github/workflows/
|
|
13
|
+
excluded-files:
|
|
14
|
+
uses: LegionIO/.github/.github/workflows/excluded-files.yml@main
|
|
15
15
|
|
|
16
16
|
security:
|
|
17
17
|
uses: LegionIO/.github/.github/workflows/security-scan.yml@main
|
|
@@ -27,8 +27,8 @@ jobs:
|
|
|
27
27
|
uses: LegionIO/.github/.github/workflows/stale.yml@main
|
|
28
28
|
|
|
29
29
|
release:
|
|
30
|
-
needs: [ci,
|
|
30
|
+
needs: [ci, excluded-files]
|
|
31
31
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
32
32
|
uses: LegionIO/.github/.github/workflows/release.yml@main
|
|
33
33
|
secrets:
|
|
34
|
-
rubygems-api-key: ${{ secrets.RUBYGEMS_API_KEY }}
|
|
34
|
+
rubygems-api-key: ${{ secrets.RUBYGEMS_API_KEY }}
|
data/.rubocop.yml
CHANGED
|
@@ -1,67 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
NewCops: enable
|
|
4
|
-
SuggestExtensions: false
|
|
1
|
+
inherit_gem:
|
|
2
|
+
rubocop-legion: config/lex.yml
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Layout/SpaceAroundEqualsInParameterDefault:
|
|
10
|
-
EnforcedStyle: space
|
|
11
|
-
|
|
12
|
-
Layout/HashAlignment:
|
|
13
|
-
EnforcedHashRocketStyle: table
|
|
14
|
-
EnforcedColonStyle: table
|
|
15
|
-
|
|
16
|
-
Metrics/MethodLength:
|
|
17
|
-
Max: 50
|
|
18
|
-
|
|
19
|
-
Metrics/ClassLength:
|
|
20
|
-
Max: 1500
|
|
21
|
-
|
|
22
|
-
Metrics/ModuleLength:
|
|
23
|
-
Max: 1500
|
|
24
|
-
|
|
25
|
-
Metrics/BlockLength:
|
|
26
|
-
Max: 40
|
|
27
|
-
Exclude:
|
|
28
|
-
- 'spec/**/*'
|
|
29
|
-
|
|
30
|
-
Metrics/AbcSize:
|
|
31
|
-
Max: 60
|
|
32
|
-
|
|
33
|
-
Metrics/CyclomaticComplexity:
|
|
34
|
-
Max: 15
|
|
35
|
-
|
|
36
|
-
Metrics/PerceivedComplexity:
|
|
37
|
-
Max: 17
|
|
38
|
-
|
|
39
|
-
Style/Documentation:
|
|
40
|
-
Enabled: false
|
|
41
|
-
|
|
42
|
-
Style/SymbolArray:
|
|
43
|
-
Enabled: true
|
|
44
|
-
|
|
45
|
-
Style/FrozenStringLiteralComment:
|
|
46
|
-
Enabled: true
|
|
47
|
-
EnforcedStyle: always
|
|
48
|
-
|
|
49
|
-
Naming/FileName:
|
|
4
|
+
# Actors define `def time` as instance method — cop looks for DSL call, false positive
|
|
5
|
+
Legion/Extension/EveryActorRequiresTime:
|
|
50
6
|
Enabled: false
|
|
51
7
|
|
|
52
|
-
|
|
8
|
+
# Runner module is designed for include into actors; not standalone
|
|
9
|
+
Legion/Extension/RunnerIncludeHelpers:
|
|
53
10
|
Enabled: false
|
|
54
11
|
|
|
55
|
-
|
|
12
|
+
# Class instance variables use Concurrent::Hash/AtomicFixnum — thread-safe by design
|
|
13
|
+
ThreadSafety/ClassInstanceVariable:
|
|
56
14
|
Enabled: false
|
|
57
15
|
|
|
16
|
+
# TelemetryEvent#build legitimately requires many named parameters for type safety
|
|
58
17
|
Metrics/ParameterLists:
|
|
59
18
|
Enabled: false
|
|
60
|
-
|
|
61
|
-
Lint/EmptyClass:
|
|
62
|
-
Exclude:
|
|
63
|
-
- 'spec/**/*'
|
|
64
|
-
|
|
65
|
-
Style/MultilineIfModifier:
|
|
66
|
-
Exclude:
|
|
67
|
-
- 'spec/**/*'
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
|
@@ -18,11 +18,11 @@ module Legion
|
|
|
18
18
|
first_line = File.open(path, &:readline)
|
|
19
19
|
data = ::JSON.parse(first_line)
|
|
20
20
|
data.is_a?(Hash) && (data.key?('sessionId') || data.key?('parentUuid'))
|
|
21
|
-
rescue StandardError
|
|
21
|
+
rescue StandardError => _e
|
|
22
22
|
false
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
def parse(path, offset: 0, &
|
|
25
|
+
def parse(path, offset: 0, &)
|
|
26
26
|
pending_tools = {}
|
|
27
27
|
session_id = nil
|
|
28
28
|
|
|
@@ -36,13 +36,13 @@ module Legion
|
|
|
36
36
|
|
|
37
37
|
if first_line && offset.zero?
|
|
38
38
|
session_id = data['sessionId'] || data['uuid'] || SecureRandom.uuid
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
39
|
+
yield(Helpers::TelemetryEvent.build(
|
|
40
|
+
event_type: :session_start,
|
|
41
|
+
session_id: session_id,
|
|
42
|
+
source: source_name,
|
|
43
|
+
timestamp: timestamp,
|
|
44
|
+
metadata: { version: data['version'] }
|
|
45
|
+
))
|
|
46
46
|
first_line = false
|
|
47
47
|
next
|
|
48
48
|
end
|
|
@@ -51,9 +51,9 @@ module Legion
|
|
|
51
51
|
msg = data['message']
|
|
52
52
|
next unless msg.is_a?(Hash)
|
|
53
53
|
|
|
54
|
-
process_assistant(msg, session_id, timestamp, pending_tools, &
|
|
55
|
-
process_tool_result(msg, session_id, timestamp, pending_tools, &
|
|
56
|
-
rescue ::JSON::ParserError
|
|
54
|
+
process_assistant(msg, session_id, timestamp, pending_tools, &) if msg['role'] == 'assistant'
|
|
55
|
+
process_tool_result(msg, session_id, timestamp, pending_tools, &) if msg['role'] == 'user'
|
|
56
|
+
rescue ::JSON::ParserError => _e
|
|
57
57
|
next
|
|
58
58
|
end
|
|
59
59
|
|
|
@@ -63,7 +63,7 @@ module Legion
|
|
|
63
63
|
|
|
64
64
|
private
|
|
65
65
|
|
|
66
|
-
def process_assistant(msg, session_id, timestamp, pending_tools
|
|
66
|
+
def process_assistant(msg, session_id, timestamp, pending_tools)
|
|
67
67
|
content = msg['content']
|
|
68
68
|
usage = msg['usage']
|
|
69
69
|
|
|
@@ -85,16 +85,16 @@ module Legion
|
|
|
85
85
|
has_tool_use = content.is_a?(Array) && content.any? { |b| b['type'] == 'tool_use' }
|
|
86
86
|
return if has_tool_use
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
88
|
+
yield(Helpers::TelemetryEvent.build(
|
|
89
|
+
event_type: :llm_request,
|
|
90
|
+
session_id: session_id,
|
|
91
|
+
source: source_name,
|
|
92
|
+
timestamp: timestamp,
|
|
93
|
+
tokens: extract_tokens(usage)
|
|
94
|
+
))
|
|
95
95
|
end
|
|
96
96
|
|
|
97
|
-
def process_tool_result(msg, session_id, timestamp, pending_tools
|
|
97
|
+
def process_tool_result(msg, session_id, timestamp, pending_tools)
|
|
98
98
|
content = msg['content']
|
|
99
99
|
return unless content.is_a?(Array)
|
|
100
100
|
|
|
@@ -106,16 +106,16 @@ module Legion
|
|
|
106
106
|
|
|
107
107
|
duration_ms = ((timestamp - pending[:timestamp]) * 1000).to_i if timestamp && pending[:timestamp]
|
|
108
108
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
109
|
+
yield(Helpers::TelemetryEvent.build(
|
|
110
|
+
event_type: :tool_call,
|
|
111
|
+
session_id: session_id,
|
|
112
|
+
source: source_name,
|
|
113
|
+
timestamp: pending[:timestamp],
|
|
114
|
+
tool_name: pending[:tool_name],
|
|
115
|
+
tool_input: pending[:tool_input],
|
|
116
|
+
duration_ms: duration_ms,
|
|
117
|
+
tokens: pending[:tokens]
|
|
118
|
+
))
|
|
119
119
|
end
|
|
120
120
|
end
|
|
121
121
|
|
|
@@ -134,7 +134,7 @@ module Legion
|
|
|
134
134
|
return nil unless str
|
|
135
135
|
|
|
136
136
|
Time.parse(str)
|
|
137
|
-
rescue ArgumentError
|
|
137
|
+
rescue ArgumentError => _e
|
|
138
138
|
nil
|
|
139
139
|
end
|
|
140
140
|
|
|
@@ -94,7 +94,7 @@ module Legion
|
|
|
94
94
|
def publish_pending(**_opts)
|
|
95
95
|
if privacy_mode?
|
|
96
96
|
count = event_store.pending.length
|
|
97
|
-
Legion::Logging.info "lex-telemetry: privacy mode active, suppressing #{count} pending events (local logging only)"
|
|
97
|
+
Legion::Logging.info "lex-telemetry: privacy mode active, suppressing #{count} pending events (local logging only)" # rubocop:disable Legion/HelperMigration/DirectLogging
|
|
98
98
|
event_store.pending.clear
|
|
99
99
|
return { success: true, published: 0, suppressed: true, reason: 'enterprise_data_privacy is enabled' }
|
|
100
100
|
end
|
|
@@ -109,7 +109,7 @@ module Legion
|
|
|
109
109
|
Transport::Messages::TelemetryMessage.new.publish(event, routing_key: routing_key)
|
|
110
110
|
published += 1
|
|
111
111
|
end
|
|
112
|
-
rescue StandardError
|
|
112
|
+
rescue StandardError => _e
|
|
113
113
|
event_store.pending.push(event)
|
|
114
114
|
end
|
|
115
115
|
|
|
@@ -149,7 +149,7 @@ module Legion
|
|
|
149
149
|
high_water_mark.set(path: path, offset: new_offset)
|
|
150
150
|
files_processed += 1
|
|
151
151
|
events_ingested += count
|
|
152
|
-
rescue StandardError
|
|
152
|
+
rescue StandardError => _e
|
|
153
153
|
next
|
|
154
154
|
end
|
|
155
155
|
end
|
|
@@ -174,7 +174,7 @@ module Legion
|
|
|
174
174
|
affinity = if defined?(Legion::Settings)
|
|
175
175
|
begin
|
|
176
176
|
Legion::Settings.dig(:region, :default_affinity)
|
|
177
|
-
rescue StandardError
|
|
177
|
+
rescue StandardError => _e
|
|
178
178
|
'prefer_local'
|
|
179
179
|
end
|
|
180
180
|
else
|
|
@@ -13,7 +13,7 @@ require 'legion/extensions/telemetry/runners/telemetry'
|
|
|
13
13
|
module Legion
|
|
14
14
|
module Extensions
|
|
15
15
|
module Telemetry
|
|
16
|
-
extend Legion::Extensions::Core if Legion::Extensions.const_defined? :Core
|
|
16
|
+
extend Legion::Extensions::Core if Legion::Extensions.const_defined? :Core, false
|
|
17
17
|
|
|
18
18
|
def self.remote_invocable?
|
|
19
19
|
false
|