memori-client 0.1.2 → 0.1.8

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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/lib/memori_client/backend/v1/asset.rb +1 -1
  3. data/lib/memori_client/backend/v2/action_log.rb +1 -1
  4. data/lib/memori_client/backend/v2/analysis.rb +1 -1
  5. data/lib/memori_client/backend/v2/asset.rb +1 -1
  6. data/lib/memori_client/backend/v2/badge.rb +1 -1
  7. data/lib/memori_client/backend/v2/completion_config.rb +1 -1
  8. data/lib/memori_client/backend/v2/consumption_log.rb +1 -1
  9. data/lib/memori_client/backend/v2/import_export.rb +1 -1
  10. data/lib/memori_client/backend/v2/integration.rb +1 -1
  11. data/lib/memori_client/backend/v2/invitation.rb +1 -1
  12. data/lib/memori_client/backend/v2/memori.rb +1 -1
  13. data/lib/memori_client/backend/v2/memori_list.rb +1 -1
  14. data/lib/memori_client/backend/v2/notification.rb +1 -1
  15. data/lib/memori_client/backend/v2/process.rb +1 -1
  16. data/lib/memori_client/backend/v2/tenant.rb +1 -1
  17. data/lib/memori_client/backend/v2/user.rb +1 -1
  18. data/lib/memori_client/configuration.rb +5 -0
  19. data/lib/memori_client/engine/hmac_helper.rb +186 -0
  20. data/lib/memori_client/engine/resource.rb +5 -31
  21. data/lib/memori_client/engine/v2/chat_log.rb +1 -1
  22. data/lib/memori_client/engine/v2/context_var.rb +1 -1
  23. data/lib/memori_client/engine/v2/correlation_pair.rb +1 -1
  24. data/lib/memori_client/engine/v2/custom_dictionary.rb +1 -1
  25. data/lib/memori_client/engine/v2/dialog.rb +1 -1
  26. data/lib/memori_client/engine/v2/event_log.rb +1 -1
  27. data/lib/memori_client/engine/v2/expert_reference.rb +1 -1
  28. data/lib/memori_client/engine/v2/function.rb +1 -1
  29. data/lib/memori_client/engine/v2/intent.rb +1 -1
  30. data/lib/memori_client/engine/v2/localization_key.rb +1 -1
  31. data/lib/memori_client/engine/v2/medium.rb +1 -1
  32. data/lib/memori_client/engine/v2/memory.rb +1 -1
  33. data/lib/memori_client/engine/v2/nlp.rb +1 -1
  34. data/lib/memori_client/engine/v2/person.rb +1 -1
  35. data/lib/memori_client/engine/v2/private/memori.rb +17 -0
  36. data/lib/memori_client/engine/v2/private/memori_block.rb +24 -0
  37. data/lib/memori_client/engine/v2/search.rb +1 -1
  38. data/lib/memori_client/engine/v2/session.rb +1 -1
  39. data/lib/memori_client/engine/v2/stat.rb +1 -1
  40. data/lib/memori_client/engine/v2/topic.rb +1 -1
  41. data/lib/memori_client/engine/v2/unanswered_question.rb +1 -1
  42. data/lib/memori_client/engine/v2/user.rb +1 -1
  43. data/lib/memori_client/engine/v2/web_hook.rb +1 -1
  44. data/lib/memori_client/http_client.rb +8 -1
  45. data/lib/memori_client/resource.rb +3 -2
  46. data/lib/memori_client/utils/rails.rb +59 -0
  47. data/lib/memori_client.rb +12 -0
  48. metadata +6 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f675f054951f807d98bebddf4be54751ec274b65748b3f2eb0b0e529ce9e1ef1
4
- data.tar.gz: ad95a4e560bc59d1e4ff728b741b49d0544b7e9e7c4e5ea9a408900755bd85f6
3
+ metadata.gz: d8da3676c32e4e5e019d67ba95e02e3c8a4ec28b0bdd7f5481f608f53cdc1da8
4
+ data.tar.gz: 1be1f7ed8f8f8a107c6b6dfb281c5c19b998686c485e5ec235014dd0e3f698ef
5
5
  SHA512:
6
- metadata.gz: 408417ff5fd64f6a853c4ca03ed94c14641f91452d981f65db9ab521e57773aa2295e2472842c03c1c12fb7fe274d1735fd66fa400c072a41832c48788757724
7
- data.tar.gz: 281ec055e3b9f4351ce52ab9dd076b4954580e8ce0796ec7ca83933afc1ffeb168f7261a55f4627dfa3f0c5c470691e07c45669a8d05b0eb14708344c65a9c0e
6
+ metadata.gz: 36677d2b337a02bf0149c09b299d48d8d892903418af277dad0c94e56e37709ae680777d46d9ba2afd17a5cd0abedf13fe48a8e850e11f86f87014fdd1a7bfef
7
+ data.tar.gz: '087b9b5e15939cd75157c698e59d5e21bd04e07f37ed10452705874f1ec52ec621eb3378aef0d3172657149f64f602bf93baecce277b70c55ae547afa51c7af3'
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:15 +0000
1
+ # Generated on 2025-01-27 20:29:51 +0000
2
2
  class MemoriClient::Backend::V1::Asset < MemoriClient::Backend::Resource
3
3
  # `GET /api/v1/GuidAsset/{assetID}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:15 +0000
1
+ # Generated on 2025-01-27 20:29:51 +0000
2
2
  class MemoriClient::Backend::V2::ActionLog < MemoriClient::Backend::Resource
3
3
  # `GET /api/v2/UserActionLogs/{strToken}/{strUserID}/{strDateFrom}/{strDateTo}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:15 +0000
1
+ # Generated on 2025-01-27 20:29:51 +0000
2
2
  class MemoriClient::Backend::V2::Analysis < MemoriClient::Backend::Resource
3
3
  # `POST /api/v2/Analysis/AnalyzeUserQuery/{strToken}/{strMemoriID}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:15 +0000
1
+ # Generated on 2025-01-27 20:29:51 +0000
2
2
  class MemoriClient::Backend::V2::Asset < MemoriClient::Backend::Resource
3
3
  # `POST /api/v2/Asset/{strToken}/{strMemoriID}/{strEngineMemoryID}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:15 +0000
1
+ # Generated on 2025-01-27 20:29:51 +0000
2
2
  class MemoriClient::Backend::V2::Badge < MemoriClient::Backend::Resource
3
3
  # `POST /api/v2/Outcome/{strToken}/{outcomeCode}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:15 +0000
1
+ # Generated on 2025-01-27 20:29:51 +0000
2
2
  class MemoriClient::Backend::V2::CompletionConfig < MemoriClient::Backend::Resource
3
3
  # `GET /api/v2/CompletionConfigs/{strToken}/{purpose}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:15 +0000
1
+ # Generated on 2025-01-27 20:29:51 +0000
2
2
  class MemoriClient::Backend::V2::ConsumptionLog < MemoriClient::Backend::Resource
3
3
  # `GET /api/v2/TenantConsumptionLogs/{strToken}/{tenantName}/{strType}/{strDateFrom}/{strDateTo}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:15 +0000
1
+ # Generated on 2025-01-27 20:29:51 +0000
2
2
  class MemoriClient::Backend::V2::ImportExport < MemoriClient::Backend::Resource
3
3
  # `POST /api/v2/ImportExport/ImportCSV/{strToken}/{strMemoriID}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:15 +0000
1
+ # Generated on 2025-01-27 20:29:51 +0000
2
2
  class MemoriClient::Backend::V2::Integration < MemoriClient::Backend::Resource
3
3
  # `GET /api/v2/Integrations/{strToken}/{strMemoriID}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:15 +0000
1
+ # Generated on 2025-01-27 20:29:51 +0000
2
2
  class MemoriClient::Backend::V2::Invitation < MemoriClient::Backend::Resource
3
3
  # `GET /api/v2/SentInvitations/{strToken}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:15 +0000
1
+ # Generated on 2025-01-27 20:29:51 +0000
2
2
  class MemoriClient::Backend::V2::Memori < MemoriClient::Backend::Resource
3
3
  # `GET /api/v2/Memori/{tenantName}/{userName}/{memoriName}/{strToken}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:15 +0000
1
+ # Generated on 2025-01-27 20:29:51 +0000
2
2
  class MemoriClient::Backend::V2::MemoriList < MemoriClient::Backend::Resource
3
3
  # `GET /api/v2/Memori/{strToken}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:15 +0000
1
+ # Generated on 2025-01-27 20:29:51 +0000
2
2
  class MemoriClient::Backend::V2::Notification < MemoriClient::Backend::Resource
3
3
  # `GET /api/v2/TenantNotifications/{tenantName}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:15 +0000
1
+ # Generated on 2025-01-27 20:29:51 +0000
2
2
  class MemoriClient::Backend::V2::Process < MemoriClient::Backend::Resource
3
3
  # `GET /api/v2/Processes/{strToken}/{strType}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:15 +0000
1
+ # Generated on 2025-01-27 20:29:51 +0000
2
2
  class MemoriClient::Backend::V2::Tenant < MemoriClient::Backend::Resource
3
3
  # `GET /api/v2/HealthCheck`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:15 +0000
1
+ # Generated on 2025-01-27 20:29:51 +0000
2
2
  class MemoriClient::Backend::V2::User < MemoriClient::Backend::Resource
3
3
  # `POST /api/v2/Login`
4
4
  #
@@ -5,6 +5,11 @@ module MemoriClient
5
5
  attr_accessor :backend_api_password
6
6
  attr_accessor :backend_api_tenant
7
7
  attr_accessor :engine_api_root
8
+ attr_accessor :engine_private_api_root
9
+
10
+ # Used to authorize private API calls to the engine
11
+ attr_accessor :engine_app_id
12
+ attr_accessor :engine_api_key
8
13
 
9
14
  # Initialize every configuration with a default.
10
15
  # Users of the gem will override these with their
@@ -0,0 +1,186 @@
1
+ require 'digest/md5'
2
+ require 'securerandom'
3
+ require 'time'
4
+
5
+ class MemoriClient::Engine::HMACHelper
6
+ IPAD = 0x36
7
+ OPAD = 0x5c
8
+
9
+ def initialize(app_id, key, max_delta_secs = 30)
10
+ # Check arguments
11
+ raise ArgumentError, "HMAC: invalid appID" if app_id.nil?
12
+ raise ArgumentError, "HMAC: invalid key" if key.nil? || key.to_s == "00000000-0000-0000-0000-000000000000"
13
+
14
+ # Initialization
15
+ @app_id = app_id
16
+ @max_delta_secs = max_delta_secs
17
+
18
+ @message_cache = {}
19
+ @cache_mutex = Mutex.new
20
+
21
+ @@next_nonce ||= 0
22
+ @nonce_mutex = Mutex.new
23
+
24
+ # Build inner and outer keys
25
+ key_bytes = guid_to_bytes(key)
26
+
27
+ inner_key_bytes = key_bytes.map { |byte| byte ^ IPAD }
28
+ @inner_key = inner_key_bytes.map { |byte| byte.to_s(16).rjust(2, '0') }.join
29
+
30
+ outer_key_bytes = key_bytes.map { |byte| byte ^ OPAD }
31
+ @outer_key = outer_key_bytes.map { |byte| byte.to_s(16).rjust(2, '0') }.join
32
+
33
+ # Start a thread for cache expiration
34
+ Thread.new do
35
+ loop do
36
+ clean_cache
37
+ sleep 1
38
+ end
39
+ end
40
+ end
41
+
42
+ # Not meant to be invoked directly, but could be used for testing
43
+ # @return [Hash] the message and the signed HMAC
44
+ def build_hmac(nonce:, epoch:)
45
+ message = "#{@app_id}:#{nonce}:#{epoch}"
46
+
47
+ # Sign the message
48
+ signature = sign(message, @inner_key, @outer_key)
49
+ [message, signature]
50
+ end
51
+
52
+ def next_hmac
53
+ nonce = @nonce_mutex.synchronize { @@next_nonce += 1 }
54
+ epoch = Time.now.utc.to_i # Use UTC time like C#
55
+ message, signature = build_hmac(nonce: nonce, epoch: epoch)
56
+
57
+ "#{message}:#{signature}"
58
+ end
59
+
60
+ def verify_hmac(hmac)
61
+ # Check arguments
62
+ raise ArgumentError, "HMAC: invalid message" if hmac.nil? || hmac.empty?
63
+
64
+ # String split HMAC message
65
+ parts = hmac.split(':')
66
+ raise ArgumentError, "HMAC: invalid message format" if parts.length != 4
67
+
68
+ # Check the app ID
69
+ begin
70
+ app_id = Integer(parts[0])
71
+ rescue
72
+ raise ArgumentError, "HMAC: invalid app ID"
73
+ end
74
+
75
+ raise ArgumentError, "HMAC: unrecognized app ID" if app_id != @app_id
76
+
77
+ # Check the nonce
78
+ begin
79
+ nonce = Integer(parts[1])
80
+ rescue
81
+ raise ArgumentError, "HMAC: invalid nonce"
82
+ end
83
+
84
+ raise ArgumentError, "HMAC: invalid nonce" if nonce < 1
85
+
86
+ # Check the timestamp
87
+ begin
88
+ timestamp = Integer(parts[2])
89
+ rescue
90
+ raise ArgumentError, "HMAC: invalid timestamp"
91
+ end
92
+
93
+ epoch = Time.now.utc.to_i # Use UTC time like C#
94
+ time_diff = epoch - timestamp
95
+ raise ArgumentError, "HMAC: timestamp out of range" if time_diff <= -@max_delta_secs || time_diff >= @max_delta_secs
96
+
97
+ # Check the signature
98
+ message = "#{app_id}:#{nonce}:#{timestamp}"
99
+ expected_signature = sign(message, @inner_key, @outer_key)
100
+ actual_signature = parts[3]
101
+
102
+ # Use a constant-time comparison to prevent timing attacks
103
+ signature_valid = secure_compare(expected_signature, actual_signature)
104
+ raise ArgumentError, "HMAC: wrong signature" unless signature_valid
105
+
106
+ # Check if the message has already been seen
107
+ is_new = false
108
+
109
+ @cache_mutex.synchronize do
110
+ unless @message_cache.key?(message)
111
+ @message_cache[message] = Time.now.to_i + 30
112
+ is_new = true
113
+ end
114
+ end
115
+
116
+ raise ArgumentError, "HMAC: message already seen" unless is_new
117
+
118
+ true
119
+ end
120
+
121
+ private
122
+
123
+ def sign(message, inner_key, outer_key)
124
+ # Compute the inner MD5 hash exactly like C#
125
+ inner_hash_bytes = Digest::MD5.digest(inner_key + message)
126
+ inner_hash_str = inner_hash_bytes.unpack1('H*')
127
+
128
+ # Compute the outer MD5 hash
129
+ outer_hash_bytes = Digest::MD5.digest(outer_key + inner_hash_str)
130
+ outer_hash_str = outer_hash_bytes.unpack1('H*')
131
+
132
+ return outer_hash_str
133
+ end
134
+
135
+ def guid_to_bytes(guid)
136
+ # Convert GUID to string if it's already an object
137
+ guid_str = guid.to_s
138
+
139
+ # Remove any curly braces and hyphens, standardize format
140
+ guid_str = guid_str.gsub(/[{}-]/, '')
141
+
142
+ # Ensure we have a valid 32-character GUID
143
+ raise ArgumentError, "Invalid GUID format" unless guid_str.length == 32
144
+
145
+ # Parse the GUID using the same byte ordering as .NET's Guid.ToByteArray()
146
+ # This matches the specific layout: Int32, Int16, Int16, byte[8]
147
+
148
+ # First 4 bytes (8 hex chars) - need to reverse byte order (little-endian)
149
+ int32_bytes = [guid_str[0, 8]].pack('H*').bytes.reverse
150
+
151
+ # Next 2 bytes (4 hex chars) - need to reverse byte order (little-endian)
152
+ int16_1_bytes = [guid_str[8, 4]].pack('H*').bytes.reverse
153
+
154
+ # Next 2 bytes (4 hex chars) - need to reverse byte order (little-endian)
155
+ int16_2_bytes = [guid_str[12, 4]].pack('H*').bytes.reverse
156
+
157
+ # Remaining 8 bytes (16 hex chars) - keep original byte order
158
+ remaining_bytes = [guid_str[16, 16]].pack('H*').bytes
159
+
160
+ # Combine all byte arrays in the correct order
161
+ return int32_bytes + int16_1_bytes + int16_2_bytes + remaining_bytes
162
+ end
163
+
164
+ def secure_compare(a, b)
165
+ return false if a.bytesize != b.bytesize
166
+
167
+ # Constant-time comparison
168
+ result = 0
169
+ a.bytes.zip(b.bytes) { |x, y| result |= x ^ y }
170
+ result == 0
171
+ end
172
+
173
+ def clean_cache
174
+ now = Time.now.to_i
175
+ @cache_mutex.synchronize do
176
+ # Remove expired entries
177
+ @message_cache.delete_if { |_, expiry| expiry < now }
178
+
179
+ # Enforce size limit
180
+ if @message_cache.size > 100000
181
+ sorted = @message_cache.sort_by { |_, expiry| expiry }
182
+ @message_cache = Hash[sorted.first(100000)]
183
+ end
184
+ end
185
+ end
186
+ end
@@ -1,39 +1,13 @@
1
1
  class MemoriClient::Engine::Resource < MemoriClient::Resource
2
- # def self.exec_http_request(method, path, args)
3
- # stop = false
4
- # processed_tokens = []
5
- # path.split('/').each do |token|
6
- # break if stop == true
7
- # if token =~ /^{.*}$/
8
- # param_name = token.match(/^{(.*)}$/).captures.first
9
- # if args[param_name.to_sym].blank?
10
- # stop = true
11
- # else
12
- # processed_tokens << args[param_name.to_sym]
13
- # end
14
- # else
15
- # processed_tokens << token
16
- # end
17
- # end
18
- #
19
- # url = processed_tokens.join('/')
20
- # url = [MemoriClient.configuration.engine_api_root, url].join('')
21
- # http = MemoriClient::HttpClient.new
22
- #
23
- # case method
24
- # when 'get'
25
- # status, body = http.get(url)
26
- # else
27
- # status, body = http.send(method, url, payload: args[:payload])
28
- # end
29
- #
30
- # [status, body]
31
- # end
32
-
33
2
  def self.build_url(url)
34
3
  [
35
4
  MemoriClient.configuration.engine_api_root,
36
5
  url
37
6
  ].join('')
38
7
  end
8
+
9
+ def self.hmac_authorization_header
10
+ helper = MemoriClient::Engine::HMACHelper.new(MemoriClient.configuration.engine_app_id, MemoriClient.configuration.engine_api_key)
11
+ ["HMAC", helper.next_hmac].join(' ')
12
+ end
39
13
  end
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:16 +0000
1
+ # Generated on 2025-01-27 20:29:52 +0000
2
2
  class MemoriClient::Engine::V2::ChatLog < MemoriClient::Engine::Resource
3
3
  # `GET /memori/v2/ChatLogs/{strSessionID}/{strDateFrom}/{strDateTo}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:16 +0000
1
+ # Generated on 2025-01-27 20:29:52 +0000
2
2
  class MemoriClient::Engine::V2::ContextVar < MemoriClient::Engine::Resource
3
3
  # `GET /memori/v2/ContextVarNames/{strSessionID}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:16 +0000
1
+ # Generated on 2025-01-27 20:29:52 +0000
2
2
  class MemoriClient::Engine::V2::CorrelationPair < MemoriClient::Engine::Resource
3
3
  # `GET /memori/v2/CorrelationPairs/{strSessionID}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:16 +0000
1
+ # Generated on 2025-01-27 20:29:52 +0000
2
2
  class MemoriClient::Engine::V2::CustomDictionary < MemoriClient::Engine::Resource
3
3
  # `GET /memori/v2/CustomWords/{strSessionID}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:16 +0000
1
+ # Generated on 2025-01-27 20:29:52 +0000
2
2
  class MemoriClient::Engine::V2::Dialog < MemoriClient::Engine::Resource
3
3
  # `POST /memori/v2/TextEnteredEvent/{strSessionID}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:16 +0000
1
+ # Generated on 2025-01-27 20:29:52 +0000
2
2
  class MemoriClient::Engine::V2::EventLog < MemoriClient::Engine::Resource
3
3
  # `GET /memori/v2/EventLogs/{strSessionID}/{strDateFrom}/{strDateTo}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:16 +0000
1
+ # Generated on 2025-01-27 20:29:52 +0000
2
2
  class MemoriClient::Engine::V2::ExpertReference < MemoriClient::Engine::Resource
3
3
  # `GET /memori/v2/ExpertReferences/{strSessionID}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:16 +0000
1
+ # Generated on 2025-01-27 20:29:52 +0000
2
2
  class MemoriClient::Engine::V2::Function < MemoriClient::Engine::Resource
3
3
  # `GET /memori/v2/MacroFunctions/{strSessionID}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:16 +0000
1
+ # Generated on 2025-01-27 20:29:52 +0000
2
2
  class MemoriClient::Engine::V2::Intent < MemoriClient::Engine::Resource
3
3
  # `GET /memori/v2/Intents/{strSessionID}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:16 +0000
1
+ # Generated on 2025-01-27 20:29:52 +0000
2
2
  class MemoriClient::Engine::V2::LocalizationKey < MemoriClient::Engine::Resource
3
3
  # `GET /memori/v2/LocalizationKeys/{strSessionID}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:16 +0000
1
+ # Generated on 2025-01-27 20:29:52 +0000
2
2
  class MemoriClient::Engine::V2::Medium < MemoriClient::Engine::Resource
3
3
  # `GET /memori/v2/Media/{strSessionID}/{strMemoryID}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:16 +0000
1
+ # Generated on 2025-01-27 20:29:52 +0000
2
2
  class MemoriClient::Engine::V2::Memory < MemoriClient::Engine::Resource
3
3
  # `GET /memori/v2/Memories/{strSessionID}/{type}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:16 +0000
1
+ # Generated on 2025-01-27 20:29:52 +0000
2
2
  class MemoriClient::Engine::V2::NLP < MemoriClient::Engine::Resource
3
3
  # `GET /memori/v2/WordVector/{strSessionID}/{word}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:16 +0000
1
+ # Generated on 2025-01-27 20:29:52 +0000
2
2
  class MemoriClient::Engine::V2::Person < MemoriClient::Engine::Resource
3
3
  # `GET /memori/v2/People/{strSessionID}`
4
4
  #
@@ -0,0 +1,17 @@
1
+ # This code is not generated by the swagger parser.
2
+ # Implements memori blocking and unblocking functionality
3
+ class MemoriClient::Engine::V2::Private::Memori < MemoriClient::Engine::Resource
4
+ def self.get_memori(strMemoriID:)
5
+ args = build_arguments(binding)
6
+ headers = { 'Authorization' => hmac_authorization_header }
7
+ args[:headers] = headers
8
+ exec_http_request('get', '/memori/v2/Memori/{strMemoriID}', **args)
9
+ end
10
+
11
+ def self.build_url(url)
12
+ [
13
+ MemoriClient.configuration.engine_private_api_root,
14
+ url
15
+ ].join('')
16
+ end
17
+ end
@@ -0,0 +1,24 @@
1
+ # This code is not generated by the swagger parser.
2
+ # Implements memori blocking and unblocking functionality
3
+ class MemoriClient::Engine::V2::Private::MemoriBlock < MemoriClient::Engine::Resource
4
+ def self.block_memori(strMemoriID:, strUntilDateTime:)
5
+ args = build_arguments(binding)
6
+ headers = { 'Authorization' => hmac_authorization_header }
7
+ args[:headers] = headers
8
+ exec_http_request('post', '/memori/v2/MemoriBlock/{strMemoriID}/{strUntilDateTime}', **args)
9
+ end
10
+
11
+ def self.unblock_memori(strMemoriID:)
12
+ args = build_arguments(binding)
13
+ headers = { 'Authorization' => hmac_authorization_header }
14
+ args[:headers] = headers
15
+ exec_http_request('delete', '/memori/v2/MemoriBlock/{strMemoriID}', **args)
16
+ end
17
+
18
+ def self.build_url(url)
19
+ [
20
+ MemoriClient.configuration.engine_private_api_root,
21
+ url
22
+ ].join('')
23
+ end
24
+ end
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:16 +0000
1
+ # Generated on 2025-01-27 20:29:52 +0000
2
2
  class MemoriClient::Engine::V2::Search < MemoriClient::Engine::Resource
3
3
  # `POST /memori/v2/Search/{strSessionID}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:16 +0000
1
+ # Generated on 2025-01-27 20:29:52 +0000
2
2
  class MemoriClient::Engine::V2::Session < MemoriClient::Engine::Resource
3
3
  # `POST /memori/v2/Session`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:16 +0000
1
+ # Generated on 2025-01-27 20:29:52 +0000
2
2
  class MemoriClient::Engine::V2::Stat < MemoriClient::Engine::Resource
3
3
  # `GET /memori/v2/TextQualityIndexes/{strSessionID}/{strLatestUpdate}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:16 +0000
1
+ # Generated on 2025-01-27 20:29:52 +0000
2
2
  class MemoriClient::Engine::V2::Topic < MemoriClient::Engine::Resource
3
3
  # `GET /memori/v2/Topics/{strSessionID}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:16 +0000
1
+ # Generated on 2025-01-27 20:29:52 +0000
2
2
  class MemoriClient::Engine::V2::UnansweredQuestion < MemoriClient::Engine::Resource
3
3
  # `GET /memori/v2/UnansweredQuestions/{strSessionID}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:16 +0000
1
+ # Generated on 2025-01-27 20:29:52 +0000
2
2
  class MemoriClient::Engine::V2::User < MemoriClient::Engine::Resource
3
3
  # `GET /memori/v2/Users/{strSessionID}`
4
4
  #
@@ -1,4 +1,4 @@
1
- # Generated on 2025-01-27 16:56:16 +0000
1
+ # Generated on 2025-01-27 20:29:52 +0000
2
2
  class MemoriClient::Engine::V2::WebHook < MemoriClient::Engine::Resource
3
3
  # `POST /memori/v2/TestSlot`
4
4
  #
@@ -72,10 +72,17 @@ class MemoriClient::HttpClient
72
72
 
73
73
  def handle_response(response, request)
74
74
  body = response.read_body
75
+
75
76
  if request['Content-Type'] == 'application/json'
77
+ if body.nil? || body == ''
78
+ response_body = {}
79
+ else
80
+ response_body = JSON.parse(body)
81
+ end
82
+
76
83
  [
77
84
  response.code,
78
- (body.nil? ? {} : JSON.parse(body))
85
+ (body.nil? ? {} : response_body)
79
86
  ]
80
87
  else
81
88
  [response.code, body]
@@ -7,6 +7,7 @@ class MemoriClient::Resource
7
7
  end
8
8
 
9
9
  def self.exec_http_request(method, path, args)
10
+ headers = args[:headers] || {}
10
11
  stop = false
11
12
  processed_tokens = []
12
13
  path.split('/').each do |token|
@@ -29,9 +30,9 @@ class MemoriClient::Resource
29
30
 
30
31
  case method
31
32
  when 'get'
32
- status, body = http.get(url)
33
+ status, body = http.get(url, headers: headers)
33
34
  else
34
- status, body = http.send(method, url, payload: args[:payload])
35
+ status, body = http.send(method, url, payload: args[:payload], headers: headers)
35
36
  end
36
37
 
37
38
  [status, body]
@@ -0,0 +1,59 @@
1
+ module MemoriClient
2
+ module Utils
3
+ module Rails
4
+ def self.copy_docs
5
+ # Find gem's root directory
6
+ gem_root = Gem.loaded_specs['memori-client'].gem_dir rescue nil
7
+ unless gem_root
8
+ puts "Error: Could not find memori_client gem installation"
9
+ exit 1
10
+ end
11
+
12
+ # Determine project root (works in Rails and non-Rails)
13
+ project_root = if defined?(::Rails)
14
+ puts 'here'
15
+ puts Dir.pwd
16
+ ::Rails.root.to_s
17
+ puts 'there'
18
+ ::Rails.root.to_s
19
+ else
20
+
21
+ Dir.pwd
22
+ end
23
+
24
+ source_docs = File.join(gem_root, 'doc')
25
+ dest_docs = File.join(project_root, 'doc', 'memori_client')
26
+
27
+ # Create destination directory if needed
28
+ FileUtils.mkdir_p(dest_docs) unless Dir.exist?(dest_docs)
29
+
30
+ # Copy all documentation files
31
+ if Dir.exist?(source_docs)
32
+ FileUtils.cp_r(Dir.glob(File.join(source_docs, '*')), dest_docs)
33
+ puts "MemoriClient documentation copied to #{dest_docs}"
34
+ else
35
+ puts "No documentation found in the gem"
36
+ end
37
+ end
38
+
39
+ def self.copy_initializer
40
+ template = <<~RUBY
41
+ # Path: config/initializers/memori_client.rb
42
+ require 'memori_client'
43
+ MemoriClient.configure do |config|
44
+ config.backend_api_root = ENV['MEMORI_BACKEND_API_ROOT']
45
+ config.backend_api_username = ENV['MEMORI_BACKEND_API_USERNAME']
46
+ config.backend_api_password = ENV['MEMORI_BACKEND_API_PASSWORD']
47
+ config.backend_api_tenant = ENV['MEMORI_BACKEND_API_TENANT']
48
+ config.engine_api_root = ENV['MEMORI_ENGINE_API_ROOT']
49
+ end
50
+ RUBY
51
+
52
+ initializer_path = ::Rails.root.join('config', 'initializers', 'memori_client.rb')
53
+ File.open(initializer_path, 'w') do |file|
54
+ file.write(template)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
data/lib/memori_client.rb CHANGED
@@ -15,7 +15,9 @@ module MemoriClient
15
15
  end
16
16
 
17
17
  module V2
18
+ module Private
18
19
 
20
+ end
19
21
  end
20
22
  end
21
23
 
@@ -42,11 +44,21 @@ end
42
44
  require 'securerandom'
43
45
  require 'uri'
44
46
  require 'json'
47
+
48
+ if defined?(::Rails)
49
+ require 'memori_client/utils/rails'
50
+ end
51
+
45
52
  require 'memori_client/configuration'
46
53
  require "memori_client/http_client"
47
54
  require "memori_client/resource"
48
55
  require "memori_client/backend/resource"
49
56
  require "memori_client/backend/resources"
57
+ require "memori_client/engine/hmac_helper"
50
58
  require "memori_client/engine/resource"
51
59
  require "memori_client/engine/resources"
52
60
 
61
+ require "memori_client/engine/v2/private/memori"
62
+ require "memori_client/engine/v2/private/memori_block"
63
+
64
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: memori-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefano Lampis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-01-27 00:00:00.000000000 Z
11
+ date: 2025-06-08 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Memori Client to interact with Memori backend and engine API
14
14
  email: me@stefanolampis.com
@@ -36,6 +36,7 @@ files:
36
36
  - lib/memori_client/backend/v2/tenant.rb
37
37
  - lib/memori_client/backend/v2/user.rb
38
38
  - lib/memori_client/configuration.rb
39
+ - lib/memori_client/engine/hmac_helper.rb
39
40
  - lib/memori_client/engine/resource.rb
40
41
  - lib/memori_client/engine/resources.rb
41
42
  - lib/memori_client/engine/v2/chat_log.rb
@@ -54,6 +55,8 @@ files:
54
55
  - lib/memori_client/engine/v2/memory.rb
55
56
  - lib/memori_client/engine/v2/nlp.rb
56
57
  - lib/memori_client/engine/v2/person.rb
58
+ - lib/memori_client/engine/v2/private/memori.rb
59
+ - lib/memori_client/engine/v2/private/memori_block.rb
57
60
  - lib/memori_client/engine/v2/prompted_question.rb
58
61
  - lib/memori_client/engine/v2/search.rb
59
62
  - lib/memori_client/engine/v2/session.rb
@@ -64,6 +67,7 @@ files:
64
67
  - lib/memori_client/engine/v2/web_hook.rb
65
68
  - lib/memori_client/http_client.rb
66
69
  - lib/memori_client/resource.rb
70
+ - lib/memori_client/utils/rails.rb
67
71
  homepage: https://rubygems.org/gems/memori_client-client
68
72
  licenses:
69
73
  - MIT