legion-tty 0.4.27 → 0.4.28

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: f1f14c29bb844005733b887586662c8c08947f757567ec9438029b423b0c991e
4
- data.tar.gz: 3e0244816b27e6174541fceba9aea3df6d87a7698f40766cf7341cf12b8ab0b0
3
+ metadata.gz: b4f86c43e057ed6d85f49e98af69b9c48bb4256751ee93ad6ca46056fce5e9a7
4
+ data.tar.gz: b474e1c01bf675a7833cdc4b1cebacef605376ed4e4ddbc61d621456c525b7cc
5
5
  SHA512:
6
- metadata.gz: 3af49d57dacb01af6ffa504d2e547d0ca920e0b675c119cdfdf95bf6f5926e5ba3f212144e3f139c005929abd52c147fa57dc06848aaae0a098a2444b84db20a
7
- data.tar.gz: cb4b0902b3c3669231ff0ffc9bbe7b198f334fa8f3f68454a79345f808313c4f13ad63ea3c01efb36225beac388b84b28dc8c2a3d2558aead4f8c0a61acb69e6
6
+ metadata.gz: 6bf396cf31f2c03c3db4b7569ed1d6c79b26506bb2316a0e05111538b35c8005d40104cdd9cb31937ed5046fe29c5f4e14b4cac33eddb897f7681e70187df132
7
+ data.tar.gz: 3f1d3a31eb2e636d4b6df7e990ba03f8f690ef31ab4bb2d1ee153e597d94698bded853e31b779a62e56eb88bae9a5423d8832f66577be0a7a053cb4a36507829
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.4.28] - 2026-03-19
4
+
5
+ ### Added
6
+ - `Legion::TTY::DaemonClient` module for daemon-first manifest fetching, intent matching, and LLM routing
7
+ - Manifest caching to `~/.legionio/catalog.json` with intent confidence threshold matching
8
+ - `chat` method for daemon-routed LLM requests via `/api/llm/chat`
9
+
3
10
  ## [0.4.27] - 2026-03-19
4
11
 
5
12
  ### Added
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'uri'
5
+ require 'json'
6
+ require 'fileutils'
7
+
8
+ module Legion
9
+ module TTY
10
+ module DaemonClient
11
+ SUCCESS_CODES = [200, 201, 202].freeze
12
+
13
+ class << self
14
+ def configure(daemon_url: 'http://127.0.0.1:4567', cache_file: nil, timeout: 5)
15
+ @daemon_url = daemon_url
16
+ @cache_file = cache_file || File.expand_path('~/.legionio/catalog.json')
17
+ @timeout = timeout
18
+ @manifest = nil
19
+ end
20
+
21
+ def available?
22
+ uri = URI("#{daemon_url}/api/health")
23
+ response = Net::HTTP.start(uri.hostname, uri.port, open_timeout: @timeout, read_timeout: @timeout) do |http|
24
+ http.get(uri.path)
25
+ end
26
+ response.code.to_i == 200
27
+ rescue StandardError
28
+ false
29
+ end
30
+
31
+ def fetch_manifest
32
+ uri = URI("#{daemon_url}/api/catalog")
33
+ response = Net::HTTP.start(uri.hostname, uri.port, open_timeout: @timeout, read_timeout: @timeout) do |http|
34
+ http.get(uri.path)
35
+ end
36
+ return nil unless response.code.to_i == 200
37
+
38
+ body = ::JSON.parse(response.body, symbolize_names: true)
39
+ @manifest = body[:data]
40
+ write_cache(@manifest)
41
+ @manifest
42
+ rescue StandardError
43
+ nil
44
+ end
45
+
46
+ def cached_manifest
47
+ return @manifest if @manifest
48
+
49
+ return nil unless @cache_file && File.exist?(@cache_file)
50
+
51
+ @manifest = ::JSON.parse(File.read(@cache_file), symbolize_names: true)
52
+ rescue StandardError
53
+ nil
54
+ end
55
+
56
+ def manifest
57
+ @manifest || cached_manifest
58
+ end
59
+
60
+ def match_intent(intent_text)
61
+ return nil unless manifest
62
+
63
+ normalized = intent_text.downcase.strip
64
+ manifest.each do |ext|
65
+ next unless ext[:known_intents]
66
+
67
+ ext[:known_intents].each do |ki|
68
+ return ki if ki[:intent]&.downcase&.strip == normalized && ki[:confidence] >= 0.8
69
+ end
70
+ end
71
+ nil
72
+ end
73
+
74
+ def chat(message:, model: nil, provider: nil)
75
+ return nil unless available?
76
+
77
+ uri = URI("#{daemon_url}/api/llm/chat")
78
+ payload = ::JSON.dump({ message: message, model: model, provider: provider })
79
+ response = post_json(uri, payload)
80
+
81
+ return nil unless response && SUCCESS_CODES.include?(response.code.to_i)
82
+
83
+ ::JSON.parse(response.body, symbolize_names: true)
84
+ rescue StandardError
85
+ nil
86
+ end
87
+
88
+ def reset!
89
+ @daemon_url = nil
90
+ @cache_file = nil
91
+ @timeout = nil
92
+ @manifest = nil
93
+ end
94
+
95
+ private
96
+
97
+ def daemon_url
98
+ @daemon_url || 'http://127.0.0.1:4567'
99
+ end
100
+
101
+ def post_json(uri, body)
102
+ req = Net::HTTP::Post.new(uri)
103
+ req['Content-Type'] = 'application/json'
104
+ req.body = body
105
+ Net::HTTP.start(uri.hostname, uri.port, open_timeout: @timeout, read_timeout: @timeout) { |h| h.request(req) }
106
+ end
107
+
108
+ def write_cache(data)
109
+ return unless @cache_file
110
+
111
+ FileUtils.mkdir_p(File.dirname(@cache_file))
112
+ File.write(@cache_file, ::JSON.dump(data))
113
+ rescue StandardError
114
+ nil
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Legion
4
4
  module TTY
5
- VERSION = '0.4.27'
5
+ VERSION = '0.4.28'
6
6
  end
7
7
  end
data/lib/legion/tty.rb CHANGED
@@ -15,6 +15,7 @@ require_relative 'tty/components/token_tracker'
15
15
  require_relative 'tty/components/tool_panel'
16
16
  require_relative 'tty/components/wizard_prompt'
17
17
  require_relative 'tty/session_store'
18
+ require_relative 'tty/daemon_client'
18
19
  require_relative 'tty/background/scanner'
19
20
  require_relative 'tty/background/github_probe'
20
21
  require_relative 'tty/background/kerberos_probe'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: legion-tty
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.27
4
+ version: 0.4.28
5
5
  platform: ruby
6
6
  authors:
7
7
  - Esity
@@ -215,6 +215,7 @@ files:
215
215
  - lib/legion/tty/components/token_tracker.rb
216
216
  - lib/legion/tty/components/tool_panel.rb
217
217
  - lib/legion/tty/components/wizard_prompt.rb
218
+ - lib/legion/tty/daemon_client.rb
218
219
  - lib/legion/tty/hotkeys.rb
219
220
  - lib/legion/tty/screen_manager.rb
220
221
  - lib/legion/tty/screens/base.rb